from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QToolBar, QAction, QMenu, QToolButton, 
    QVBoxLayout, QWidget, QHBoxLayout, QLabel, QPushButton, QTextEdit, 
    QFileDialog, QComboBox, QProgressBar, QMessageBox, QDesktopWidget, QSplitter, QTabWidget,
    QListWidget, QListWidgetItem
)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer
from PyQt5.QtGui import QIcon, QFont, QPixmap, QColor
import os
import traceback
import glob

from common import app_version, ffplay_executable_cmd
from core import MediaConverter
from styles import style_manager
from video_converter import VideoConverter
from audio_converter import AudioConverter
from image_converter import ImageConverter
import subprocess


class ConversionThread(QThread):
    """转换任务线程"""
    finished = pyqtSignal(str)  # 转换完成信号
    error = pyqtSignal(str)     # 错误信号
    progress = pyqtSignal(str)  # 进度信号

    def __init__(self, converter, conversion_type, file_path, **kwargs):
        super().__init__()
        self.converter = converter
        self.conversion_type = conversion_type
        self.file_path = file_path
        self.kwargs = kwargs

    def run(self):
        try:
            self.progress.emit("开始转换...")
            
            # 检查文件是否存在
            if not os.path.exists(self.file_path):
                raise Exception(f"文件不存在: {self.file_path}")
            
            self.progress.emit("正在处理文件...")
            
            if self.conversion_type == "video":
                # 视频转换进度更新
                self.progress.emit("正在读取视频...")
                result = self.converter.convert_video(self.file_path)
                self.progress.emit("视频处理完成...")
            elif self.conversion_type == "audio":
                # 音频转换进度更新
                self.progress.emit("正在读取音频...")
                result = self.converter.convert_audio(self.file_path, **self.kwargs)
                self.progress.emit("音频处理完成...")
            elif self.conversion_type == "image":
                # 图片转换进度更新
                self.progress.emit("正在读取图片...")
                result = self.converter.convert_image(self.file_path, **self.kwargs)
                self.progress.emit("图片处理完成...")
            else:
                raise Exception("未知的转换类型")
            
            self.progress.emit("转换即将完成...")
                
            if result:
                self.progress.emit("转换完成")
                self.finished.emit(result)
            else:
                raise Exception("转换失败，未生成输出文件")
        except Exception as e:
            import traceback
            error_msg = f"{str(e)}\n\n详细错误信息:\n{traceback.format_exc()}"
            self.error.emit(error_msg)


class BatchConversionThread(QThread):
    """批量转换任务线程"""
    progress_updated = pyqtSignal(int, int)  # current, total
    file_converted = pyqtSignal(str, bool, str)  # file_path, success, message
    finished = pyqtSignal(int, int)  # total_files, successful_files
    error = pyqtSignal(str)

    def __init__(self, file_list, converter, media_type='video', output_format=None):
        super().__init__()
        self.file_list = file_list
        self.converter = converter
        self.media_type = media_type
        self.output_format = output_format
        self.should_stop = False

    def run(self):
        try:
            total_files = len(self.file_list)
            successful_conversions = 0
            failed_conversions = 0
            
            for i, input_file in enumerate(self.file_list):
                if self.should_stop:
                    break
                
                try:
                    # 根据媒体类型选择转换方法
                    if self.media_type == 'audio':
                        result = self.converter.convert_audio(input_file, self.output_format or 'wav')
                    elif self.media_type == 'image':
                        result = self.converter.convert_image(input_file, self.output_format or 'jpg')
                    else:
                        result = self.converter.convert_video(input_file)
                    
                    if result and os.path.exists(result):
                        successful_conversions += 1
                        self.file_converted.emit(input_file, True, f"转换成功: {os.path.basename(result)}")
                    else:
                        failed_conversions += 1
                        self.file_converted.emit(input_file, False, "转换失败")
                    
                except Exception as e:
                    failed_conversions += 1
                    self.file_converted.emit(input_file, False, str(e))
                
                # 更新进度
                self.progress_updated.emit(i + 1, total_files)
            
            # 发送完成信号
            if not self.should_stop:
                self.finished.emit(total_files, successful_conversions)
            
        except Exception as e:
            self.error.emit(f"批量转换过程中发生错误: {str(e)}")
    
    def stop(self):
        self.should_stop = True


class AllConversionThread(QThread):
    """全部转换线程"""
    progress_updated = pyqtSignal(int)  # 进度更新信号 (百分比)
    file_converted = pyqtSignal(str)    # 文件转换完成信号
    conversion_finished = pyqtSignal(int, int, int)  # 转换完成信号 (总数, 成功数, 失败数)
    error_occurred = pyqtSignal(str)    # 错误信号
    
    def __init__(self, file_list, source_folder, target_folder):
        super().__init__()
        self.file_list = file_list
        self.source_folder = source_folder
        self.target_folder = target_folder
        self.should_stop = False
        
        # 初始化转换器
        self.video_converter = VideoConverter()
        self.audio_converter = AudioConverter()
        self.image_converter = ImageConverter()
    
    def run(self):
        try:
            total_files = len(self.file_list)
            success_count = 0
            error_count = 0
            
            for i, file_path in enumerate(self.file_list):
                if self.should_stop:
                    break
                
                try:
                    # 计算相对路径
                    rel_path = os.path.relpath(file_path, self.source_folder)
                    
                    # 确定文件类型和转换方法
                    file_ext = os.path.splitext(file_path)[1].lower()
                    
                    if file_ext in ['.mp4', '.avi', '.mov', '.mkv', '.flv', '.wmv']:
                        # 视频转换
                        output_file = self._convert_video_file(file_path, rel_path)
                    elif file_ext in ['.mp3', '.wav', '.aac', '.flac', '.ogg', '.m4a']:
                        # 音频转换
                        output_file = self._convert_audio_file(file_path, rel_path)
                    elif file_ext in ['.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff']:
                        # 图片转换
                        output_file = self._convert_image_file(file_path, rel_path)
                    else:
                        raise Exception(f"不支持的文件格式: {file_ext}")
                    
                    if output_file:
                        success_count += 1
                        self.file_converted.emit(f"✓ {os.path.basename(file_path)} -> {os.path.basename(output_file)}")
                    else:
                        error_count += 1
                        self.file_converted.emit(f"✗ {os.path.basename(file_path)} 转换失败")
                
                except Exception as e:
                    error_count += 1
                    self.file_converted.emit(f"✗ {os.path.basename(file_path)}: {str(e)}")
                
                # 更新进度
                progress = int((i + 1) * 100 / total_files)
                self.progress_updated.emit(progress)
            
            # 发送完成信号
            if not self.should_stop:
                self.conversion_finished.emit(total_files, success_count, error_count)
        
        except Exception as e:
            self.error_occurred.emit(f"转换过程中发生错误: {str(e)}")
    
    def _convert_video_file(self, input_path, rel_path):
        """转换视频文件"""
        try:
            # 构建输出路径，保持目录结构
            output_dir = os.path.join(self.target_folder, os.path.dirname(rel_path))
            os.makedirs(output_dir, exist_ok=True)
            
            # 生成输出文件名（保持原文件名，改为mp4扩展名）
            base_name = os.path.splitext(os.path.basename(input_path))[0]
            output_path = os.path.join(output_dir, f"{base_name}.mp4")
            
            # 使用视频转换器进行转换
            temp_output = self.video_converter.convert_video(input_path)
            
            # 将临时文件移动到目标位置
            if temp_output and os.path.exists(temp_output):
                if temp_output != output_path:
                    import shutil
                    shutil.move(temp_output, output_path)
                return output_path
            
            return None
        except Exception as e:
            raise Exception(f"视频转换失败: {str(e)}")
    
    def _convert_audio_file(self, input_path, rel_path):
        """转换音频文件"""
        try:
            # 构建输出路径，保持目录结构
            output_dir = os.path.join(self.target_folder, os.path.dirname(rel_path))
            os.makedirs(output_dir, exist_ok=True)
            
            # 生成输出文件名（保持原文件名，改为wav扩展名）
            base_name = os.path.splitext(os.path.basename(input_path))[0]
            output_path = os.path.join(output_dir, f"{base_name}.wav")
            
            # 使用音频转换器进行转换
            temp_output = self.audio_converter.convert_audio(input_path, "wav")
            
            # 将临时文件移动到目标位置
            if temp_output and os.path.exists(temp_output):
                if temp_output != output_path:
                    import shutil
                    shutil.move(temp_output, output_path)
                return output_path
            
            return None
        except Exception as e:
            raise Exception(f"音频转换失败: {str(e)}")
    
    def _convert_image_file(self, input_path, rel_path):
        """转换图片文件"""
        try:
            # 构建输出路径，保持目录结构
            output_dir = os.path.join(self.target_folder, os.path.dirname(rel_path))
            os.makedirs(output_dir, exist_ok=True)
            
            # 生成输出文件名（保持原文件名，改为jpg扩展名）
            base_name = os.path.splitext(os.path.basename(input_path))[0]
            output_path = os.path.join(output_dir, f"{base_name}.jpg")
            
            # 使用图片转换器进行转换
            temp_output = self.image_converter.convert_image(input_path, "jpg")
            
            # 将临时文件移动到目标位置
            if temp_output and os.path.exists(temp_output):
                if temp_output != output_path:
                    import shutil
                    shutil.move(temp_output, output_path)
                return output_path
            
            return None
        except Exception as e:
            raise Exception(f"图片转换失败: {str(e)}")
    
    def stop(self):
        self.should_stop = True


class PlaybackMonitorThread(QThread):
    """播放监控线程"""
    playback_finished = pyqtSignal()  # 播放完成信号
    
    def __init__(self, ffplay_process, parent_window):
        super().__init__()
        self.ffplay_process = ffplay_process
        self.parent_window = parent_window
        self.should_stop = False
    
    def run(self):
        """监控播放状态"""
        try:
            if self.ffplay_process and not self.should_stop:
                # 等待进程结束
                self.ffplay_process.wait()
                
                # 播放结束，更新状态
                if not self.should_stop:
                    self.parent_window.is_playing = False
                    self.parent_window.is_paused = False
                    self.parent_window.ffplay_process = None
                    
                    # 发送播放完成信号
                    self.playback_finished.emit()
        except Exception as e:
            print(f"监控播放状态时出错: {str(e)}")
    
    def stop(self):
        """停止监控"""
        self.should_stop = True
        self.quit()


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        try:
            self.setWindowTitle("多媒体转换工具")
            self.resize(900, 700)
            
            # 初始化转换器
            try:
                self.converter = MediaConverter()
            except Exception as e:
                QMessageBox.critical(None, "初始化错误", f"无法初始化媒体转换器: {str(e)}")
                raise
            
            self.conversion_thread = None
            
            # 设置应用图标
            self._setup_icon()
            
            # 文件路径存储
            self.current_file_paths = {
                'video': None,
                'audio': None,
                'image': None
            }
            
            # 文件夹路径存储
            self.current_video_folder = None
            self.current_audio_folder = None
            self.current_image_folder = None
            
            # 全部转换相关的文件夹路径
            self.all_source_folder = None
            self.all_target_folder = None
            
            # 播放器窗口位置调整防抖定时器
            self.player_position_timer = QTimer()
            self.player_position_timer.setSingleShot(True)
            self.player_position_timer.timeout.connect(self._restart_ffplay_with_new_size)
            
            # 初始化UI组件引用
            self.result_text = None
            self.progress_bar = None
            self.audio_format_combo = None
            self.image_format_combo = None
            
            self._setup_ui()
            self._setup_styles()
            self._setup_window_properties()
        except Exception as e:
            QMessageBox.critical(None, "初始化错误", f"程序初始化失败: {str(e)}")
            raise
    
    def _setup_styles(self):
        """设置样式"""
        self.apply_styles()
    
    def _setup_window_properties(self):
        """设置窗口属性以确保跨平台一致性"""
        # 获取屏幕尺寸
        screen = QApplication.desktop().screenGeometry()
        
        # 设置窗口最小尺寸（使用相对尺寸）
        min_width = max(800, int(screen.width() * 0.4))
        min_height = max(600, int(screen.height() * 0.5))
        self.setMinimumSize(min_width, min_height)
        
        # 设置初始窗口尺寸
        initial_width = max(1000, int(screen.width() * 0.6))
        initial_height = max(750, int(screen.height() * 0.7))
        self.resize(initial_width, initial_height)
        
        # 居中显示
        self.move(
            (screen.width() - initial_width) // 2,
            (screen.height() - initial_height) // 2
        )

    def _setup_icon(self):
        """设置应用图标"""
        try:
            # 获取图标文件路径
            icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'icon.jpg')
            
            if os.path.exists(icon_path):
                # 创建图标对象
                icon = QIcon(icon_path)
                
                # 检查图标是否有效
                if not icon.isNull():
                    # 设置窗口图标（左上角和任务栏）
                    self.setWindowIcon(icon)
                    
                    # 设置应用程序图标（全局）
                    app_instance = QApplication.instance()
                    if app_instance:
                        app_instance.setWindowIcon(icon)
                else:
                    print(f"警告：图标文件无效: {icon_path}")
            else:
                print(f"警告：图标文件不存在: {icon_path}")
        except Exception as e:
            print(f"设置图标时出错: {e}")

    def _setup_ui(self):
        """设置UI界面"""
        # 创建工具栏
        toolbar = QToolBar("Main Toolbar")
        self.addToolBar(toolbar)

        # 创建"统一处理"菜单按钮
        process_menu = QMenu("统一处理", self)

        # 获取图标
        video_icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'video.jpg')
        video_icon = QIcon(video_icon_path) if os.path.exists(video_icon_path) else QIcon()
        audio_icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'audio.jpg')
        audio_icon = QIcon(audio_icon_path) if os.path.exists(audio_icon_path) else QIcon()
        image_icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'image.jpg')
        image_icon = QIcon(image_icon_path) if os.path.exists(image_icon_path) else QIcon()

        # 添加四个子菜单
        video_action = QAction(video_icon, "视频", self)
        audio_action = QAction(audio_icon, "音频", self)
        image_action = QAction(image_icon, "图片", self)
        all_action = QAction("全部", self)

        process_menu.addAction(video_action)
        process_menu.addAction(audio_action)
        process_menu.addAction(image_action)
        process_menu.addAction(all_action)

        # 将"统一处理"菜单添加到工具栏作为按钮
        process_button = QToolButton(self)
        process_button.setText("统一处理")
        process_button.setMenu(process_menu)
        process_button.setPopupMode(QToolButton.MenuButtonPopup)
        toolbar.addWidget(process_button)

        # 添加播放器按钮
        player_action = QAction("播放器（试用）", self)
        toolbar.addAction(player_action)

        # 添加关于按钮
        about_action = QAction("关于", self)
        toolbar.addAction(about_action)

        # 绑定事件
        video_action.triggered.connect(lambda: self.switch_ui('video'))
        audio_action.triggered.connect(lambda: self.switch_ui('audio'))
        image_action.triggered.connect(lambda: self.switch_ui('image'))
        all_action.triggered.connect(lambda: self.switch_ui('all'))
        player_action.triggered.connect(lambda: self.switch_ui('player'))
        about_action.triggered.connect(lambda: self.switch_ui('about'))

        # 主界面中央widget
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        
        # 显示欢迎界面
        self.show_welcome_ui()

    def apply_styles(self):
        """应用样式"""
        # 获取DPI缩放因子并更新样式管理器
        screen = QApplication.desktop().screen()
        dpi = screen.logicalDpiX()
        scale_factor = dpi / 96.0  # 96 DPI是标准DPI
        style_manager.scale_factor = scale_factor
        style_manager.base_font_size = max(9, int(10 * scale_factor))
        style_manager.button_font_size = max(9, int(10 * scale_factor))
        
        # 应用主样式表
        self.setStyleSheet(style_manager.get_main_stylesheet())

    def show_welcome_ui(self):
        """显示主界面基础信息"""
        self.clear_central_widget_layout()
        layout = QVBoxLayout()
        layout.setAlignment(Qt.AlignCenter)
        layout.setSpacing(20)
        layout.setContentsMargins(50, 50, 50, 50)

        # 标题
        title_label = QLabel("多媒体转换工具")
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setStyleSheet(style_manager.get_title_label_style())
        
        # 版本信息
        version_label = QLabel(f"版本 {app_version}")
        version_label.setAlignment(Qt.AlignCenter)
        version_label.setStyleSheet(style_manager.get_version_label_style())
        
        # 作者信息
        author_label = QLabel("作者：Jake")
        author_label.setAlignment(Qt.AlignCenter)
        author_label.setStyleSheet(style_manager.get_author_label_style())
        
        # 功能更新列表标题
        features_title = QLabel("功能特性")
        features_title.setAlignment(Qt.AlignCenter)
        features_title.setStyleSheet(style_manager.get_features_title_style())
        
        # 功能列表
        features_text = QTextEdit()
        features_text.setReadOnly(True)
        features_text.setMaximumHeight(220)
        features_text.setStyleSheet(style_manager.get_features_text_style())
        
        features_content = """
• 视频转换：支持多种格式转换为1080x1920竖屏格式
  - 支持格式：MP4, AVI, MOV, MKV, FLV, WMV
  - 自动裁剪和缩放，保持最佳画质
  - 保留原始音频轨道

• 音频转换：高质量音频格式转换
  - WAV (16kHz)：适合语音处理
  - MP3 (128kbps)：平衡质量与文件大小
  - AAC (64kbps)：高压缩比格式

• 图片转换：智能图片处理
  - 支持格式：JPG, PNG, BMP, GIF, TIFF
  - 自动调整为1080x1920分辨率
  - 居中裁剪，保持图片主要内容

• 多线程处理：转换过程不阻塞界面操作
• 跨平台支持：Windows, macOS, Linux
        """
        
        features_text.setPlainText(features_content)
        
        # 使用说明
        instruction_label = QLabel("请从上方工具栏选择要转换的媒体类型开始使用")
        instruction_label.setAlignment(Qt.AlignCenter)
        instruction_label.setStyleSheet(style_manager.get_instruction_label_style())

        # 添加所有组件到布局
        layout.addWidget(title_label)
        layout.addWidget(version_label)
        layout.addWidget(author_label)
        layout.addWidget(features_title)
        layout.addWidget(features_text)
        layout.addWidget(instruction_label)

        self.central_widget.setLayout(layout)

    def _create_file_selection_widget(self, media_type, file_filter):
        """创建文件选择组件"""
        widget = QWidget()
        layout = QHBoxLayout()
        widget.setLayout(layout)

        # 媒体类型中英文映射
        type_map = {
            'video': '视频',
            'audio': '音频', 
            'image': '图片'
        }
        display_name = type_map.get(media_type, media_type)

        # 文件路径标签
        current_file = self.current_file_paths.get(media_type)
        if current_file:
            path_label = QLabel(os.path.basename(current_file))
        else:
            path_label = QLabel(f"未选择{display_name}文件")
        path_label.setMinimumWidth(280)
        path_label.setStyleSheet(style_manager.get_path_label_style())
        
        # 选择文件按钮
        select_button = QPushButton(f"选择{display_name}文件")
        select_button.clicked.connect(lambda: self._select_file(media_type, file_filter, path_label))
        
        # 转换按钮
        convert_button = QPushButton(f"转换{display_name}")
        
        layout.addWidget(path_label)
        layout.addWidget(select_button)
        layout.addWidget(convert_button)
        
        return widget, path_label, convert_button

    def _select_file(self, media_type, file_filter, path_label):
        """选择文件"""
        try:
            # 媒体类型中英文映射
            type_map = {
                'video': '视频',
                'audio': '音频', 
                'image': '图片'
            }
            display_name = type_map.get(media_type, media_type)
            
            # 添加 options 参数避免使用原生对话框，解决 macOS NSOpenPanel 兼容性问题
            file_path, _ = QFileDialog.getOpenFileName(
                self, 
                f"选择{display_name}文件", 
                "", 
                file_filter,
                options=QFileDialog.DontUseNativeDialog
            )
            if file_path:
                # 验证文件是否存在且可读
                if os.path.exists(file_path) and os.access(file_path, os.R_OK):
                    self.current_file_paths[media_type] = file_path
                    path_label.setText(os.path.basename(file_path))
                    if hasattr(self, 'result_text') and self.result_text:
                        self.result_text.clear()
                    
                    # 如果是视频文件，更新视频文件列表显示
                    if media_type == 'video' and hasattr(self, 'video_file_list') and hasattr(self, 'video_path_label'):
                        self._update_video_file_list()
                    # 如果是音频文件，更新音频文件列表显示
                    elif media_type == 'audio' and hasattr(self, 'audio_file_list') and hasattr(self, 'audio_path_label'):
                        self._update_audio_file_list()
                    # 如果是图片文件，更新图片文件列表显示
                    elif media_type == 'image' and hasattr(self, 'image_file_list') and hasattr(self, 'image_path_label'):
                        self._update_image_file_list()
                else:
                    QMessageBox.warning(self, "警告", f"文件不存在或无法访问: {file_path}")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"选择文件时出错: {str(e)}")

    def _create_result_widget(self):
        """创建结果显示组件"""
        self.result_text = QTextEdit()
        self.result_text.setReadOnly(True)
        self.result_text.setMinimumHeight(100)  # 设置最小高度而不是固定高度
        self.result_text.setMaximumHeight(300)  # 设置最大高度，允许在范围内自适应
        
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        self.progress_bar.setMinimum(0)
        self.progress_bar.setMaximum(100)
        self.progress_bar.setValue(0)
        self.progress_bar.setTextVisible(True)
        
        return self.result_text, self.progress_bar

    def show_video_ui(self):
        """显示视频转换界面"""
        main_layout = QVBoxLayout()
        main_layout.setSpacing(0)
        main_layout.setContentsMargins(15, 15, 15, 15)

        # 顶部标题区域 - 占1/10
        title_widget = QWidget()
        title_widget.setFixedHeight(60)
        title_layout = QVBoxLayout()
        title_layout.setContentsMargins(0, 0, 0, 0)
        title_widget.setLayout(title_layout)
        
        title = QLabel("视频转换")
        title.setStyleSheet(style_manager.get_interface_title_style())
        title.setAlignment(Qt.AlignCenter)
        title_layout.addWidget(title)
        main_layout.addWidget(title_widget)

        # 中间内容区域 - 占7/10
        middle_widget = QWidget()
        middle_layout = QHBoxLayout()
        middle_layout.setSpacing(10)
        middle_layout.setContentsMargins(0, 10, 0, 10)
        middle_widget.setLayout(middle_layout)
        
        # 左侧文件显示区域 - 占4/10
        left_widget = QWidget()
        left_widget.setStyleSheet(style_manager.get_left_widget_style())
        left_layout = QVBoxLayout()
        left_layout.setContentsMargins(10, 10, 10, 10)
        left_widget.setLayout(left_layout)
        
        # 文件列表标题
        file_list_title = QLabel("选择的文件")
        file_list_title.setStyleSheet(style_manager.get_file_list_title_style())
        left_layout.addWidget(file_list_title)
        
        # 文件列表显示区域
        self.video_file_list = QTextEdit()
        self.video_file_list.setReadOnly(True)
        self.video_file_list.setStyleSheet(style_manager.get_file_list_style())
        self.video_file_list.setPlaceholderText("暂无选择文件")
        left_layout.addWidget(self.video_file_list)
        
        # 右侧标签页区域 - 占6/10
        right_widget = QWidget()
        right_layout = QVBoxLayout()
        right_layout.setContentsMargins(0, 0, 0, 0)
        right_widget.setLayout(right_layout)
        
        # 创建标签页
        self.video_tab_widget = QTabWidget()
        self.video_tab_widget.setStyleSheet(style_manager.get_tab_widget_style())
        
        # 单个转换标签页
        single_tab = QWidget()
        single_layout = QVBoxLayout()
        single_layout.setContentsMargins(15, 15, 15, 15)
        single_tab.setLayout(single_layout)
        
        # 原来的文件选择和转换按钮
        file_widget, self.video_path_label, self.video_convert_button = self._create_file_selection_widget(
            "video", "视频文件 (*.mp4 *.avi *.mov *.mkv *.flv *.wmv)"
        )
        single_layout.addWidget(file_widget)
        single_layout.addStretch()
        
        # 批量转换标签页
        batch_tab = QWidget()
        batch_layout = QVBoxLayout()
        batch_layout.setContentsMargins(15, 15, 15, 15)
        batch_tab.setLayout(batch_layout)
        
        # 文件夹选择按钮
        folder_select_widget = QWidget()
        folder_select_layout = QHBoxLayout()
        folder_select_widget.setLayout(folder_select_layout)
        
        self.video_folder_button = QPushButton("选择文件夹")
        self.video_folder_button.setStyleSheet(style_manager.get_folder_button_style())
        
        self.video_folder_path_label = QLabel("未选择文件夹")
        self.video_folder_path_label.setStyleSheet(style_manager.get_path_label_style())
        
        folder_select_layout.addWidget(self.video_folder_button)
        folder_select_layout.addWidget(self.video_folder_path_label, 1)
        batch_layout.addWidget(folder_select_widget)
        
        # 批量转换按钮
        self.video_batch_convert_button = QPushButton("开始批量转换")
        self.video_batch_convert_button.setStyleSheet(style_manager.get_batch_convert_button_style())
        self.video_batch_convert_button.setEnabled(False)
        batch_layout.addWidget(self.video_batch_convert_button)
        batch_layout.addStretch()
        
        # 添加标签页
        self.video_tab_widget.addTab(single_tab, "单个")
        self.video_tab_widget.addTab(batch_tab, "批量")
        right_layout.addWidget(self.video_tab_widget)
        
        # 设置左右比例 4:6
        middle_layout.addWidget(left_widget, 4)
        middle_layout.addWidget(right_widget, 6)
        main_layout.addWidget(middle_widget, 7)

        # 底部信息提示区域 - 占2/10
        bottom_widget = QWidget()
        bottom_widget.setFixedHeight(120)
        bottom_layout = QVBoxLayout()
        bottom_layout.setContentsMargins(0, 10, 0, 0)
        bottom_widget.setLayout(bottom_layout)
        
        # 进度条
        self.video_progress_bar = QProgressBar()
        self.video_progress_bar.setVisible(False)
        self.video_progress_bar.setMinimum(0)
        self.video_progress_bar.setMaximum(100)
        self.video_progress_bar.setValue(0)
        self.video_progress_bar.setTextVisible(True)
        bottom_layout.addWidget(self.video_progress_bar)
        
        # 信息显示区域
        self.video_result_text = QTextEdit()
        self.video_result_text.setReadOnly(True)
        self.video_result_text.setStyleSheet(style_manager.get_result_text_style())
        self.video_result_text.setPlaceholderText("支持多种视频格式转换，输出为1080x1920竖屏格式")
        self.video_result_text.setMinimumHeight(100)  # 设置最小高度
        self.video_result_text.setMaximumHeight(300)  # 设置最大高度，允许滚动查看更多内容
        bottom_layout.addWidget(self.video_result_text)
        main_layout.addWidget(bottom_widget, 2)

        self.central_widget.setLayout(main_layout)
        
        # 绑定事件
        self.video_convert_button.clicked.connect(lambda: self._start_conversion('video'))
        self.video_folder_button.clicked.connect(self._select_video_folder)
        self.video_batch_convert_button.clicked.connect(self._start_batch_conversion)
        
        # 监听文件选择变化
        # self.video_path_label.textChanged = self._update_video_file_list  # 注释掉，因为QLabel没有textChanged信号
        
        # 恢复之前的文件夹选择状态
        self._restore_video_folder_state()
     
    def _restore_video_folder_state(self):
        """恢复视频文件夹选择状态"""
        try:
            if hasattr(self, 'current_video_folder') and self.current_video_folder:
                if os.path.exists(self.current_video_folder) and os.access(self.current_video_folder, os.R_OK):
                    # 更新UI显示
                    folder_name = os.path.basename(self.current_video_folder)
                    self.video_folder_path_label.setText(folder_name)
                    
                    # 重新扫描视频文件
                    video_extensions = ['.mp4', '.avi', '.mov', '.mkv', '.wmv', '.flv', '.webm']
                    video_files = []
                    
                    for file_name in os.listdir(self.current_video_folder):
                        file_path = os.path.join(self.current_video_folder, file_name)
                        if os.path.isfile(file_path):
                            _, ext = os.path.splitext(file_name)
                            if ext.lower() in video_extensions:
                                video_files.append(file_name)
                    
                    # 更新文件列表显示和按钮状态
                    if video_files:
                        file_list_text = "\n".join([f"• {file}" for file in video_files])
                        self.video_file_list.setText(file_list_text)
                        self.video_batch_convert_button.setEnabled(True)
                    else:
                        self.video_file_list.setText("该文件夹中没有找到视频文件")
                        self.video_batch_convert_button.setEnabled(False)
                else:
                    # 如果文件夹不存在或不可访问，清除状态
                    self.current_video_folder = None
        except Exception as e:
            print(f"恢复视频文件夹状态时出错: {e}")
    
    def _select_video_folder(self):
        """选择视频文件夹"""
        try:
            folder_path = QFileDialog.getExistingDirectory(
                self, "选择包含视频文件的文件夹", "",
                QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks | QFileDialog.DontUseNativeDialog
            )
            
            if folder_path:
                # 检查文件夹是否存在且可访问
                if os.path.exists(folder_path) and os.access(folder_path, os.R_OK):
                    self.video_folder_path_label.setText(os.path.basename(folder_path))
                    self.video_batch_convert_button.setEnabled(True)
                    
                    # 扫描文件夹中的视频文件
                    video_extensions = ['.mp4', '.avi', '.mov', '.mkv', '.flv', '.wmv']
                    video_files = []
                    
                    for file_name in os.listdir(folder_path):
                        file_path = os.path.join(folder_path, file_name)
                        if os.path.isfile(file_path):
                            _, ext = os.path.splitext(file_name.lower())
                            if ext in video_extensions:
                                video_files.append(file_name)
                    
                    # 更新文件列表显示
                    if video_files:
                        file_list_text = f"文件夹: {os.path.basename(folder_path)}\n\n找到 {len(video_files)} 个视频文件:\n"
                        for i, file_name in enumerate(video_files[:10], 1):  # 最多显示10个
                            file_list_text += f"{i}. {file_name}\n"
                        if len(video_files) > 10:
                            file_list_text += f"... 还有 {len(video_files) - 10} 个文件"
                        self.video_file_list.setText(file_list_text)
                    else:
                        self.video_file_list.setText(f"文件夹: {os.path.basename(folder_path)}\n\n未找到支持的视频文件")
                        self.video_batch_convert_button.setEnabled(False)
                    
                    # 保存文件夹路径
                    self.current_video_folder = folder_path
                else:
                    QMessageBox.warning(self, "警告", f"文件夹不存在或无法访问: {folder_path}")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"选择文件夹时出错: {str(e)}")
    
    def _start_batch_conversion(self):
        """开始批量转换"""
        try:
            if not hasattr(self, 'current_video_folder') or not self.current_video_folder:
                QMessageBox.warning(self, "警告", "请先选择包含视频文件的文件夹")
                return
            
            # 获取文件夹中的所有视频文件
            video_extensions = ['.mp4', '.avi', '.mov', '.mkv', '.flv', '.wmv']
            video_files = []
            
            for file_name in os.listdir(self.current_video_folder):
                file_path = os.path.join(self.current_video_folder, file_name)
                if os.path.isfile(file_path):
                    _, ext = os.path.splitext(file_name.lower())
                    if ext in video_extensions:
                        video_files.append(file_path)
            
            if not video_files:
                QMessageBox.warning(self, "警告", "选择的文件夹中没有找到支持的视频文件")
                return
            
            # 确认批量转换
            reply = QMessageBox.question(
                self, "确认批量转换", 
                f"找到 {len(video_files)} 个视频文件，确定要开始批量转换吗？\n\n转换可能需要较长时间。",
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.No
            )
            
            if reply == QMessageBox.Yes:
                # 开始批量转换
                self._start_batch_conversion_process(video_files)
                
        except Exception as e:
            QMessageBox.critical(self, "错误", f"批量转换时出错: {str(e)}")
    
    def _start_batch_conversion_process(self, video_files):
        """执行批量转换过程"""
        try:
            # 检查是否有转换正在进行
            if hasattr(self, 'conversion_thread') and self.conversion_thread and self.conversion_thread.isRunning():
                QMessageBox.warning(self, "警告", "已有转换任务正在进行中，请等待完成后再试")
                return
            
            # 清空之前的结果
            if hasattr(self, 'video_result_text') and self.video_result_text:
                self.video_result_text.clear()
            if hasattr(self, 'video_progress_bar') and self.video_progress_bar:
                self.video_progress_bar.setVisible(True)
                self.video_progress_bar.setValue(0)
                self.video_progress_bar.setMaximum(len(video_files))
            
            # 禁用相关按钮
            if hasattr(self, 'video_batch_convert_button') and self.video_batch_convert_button:
                self.video_batch_convert_button.setEnabled(False)
            if hasattr(self, 'video_folder_button') and self.video_folder_button:
                self.video_folder_button.setEnabled(False)
            
            # 显示开始信息
            if hasattr(self, 'video_result_text') and self.video_result_text:
                self.video_result_text.append(f"开始批量转换 {len(video_files)} 个视频文件...\n")
            
            # 创建批量转换线程
            self.batch_conversion_thread = BatchConversionThread(video_files, self.converter, 'video')
            self.batch_conversion_thread.progress_updated.connect(self._on_batch_progress)
            self.batch_conversion_thread.file_converted.connect(self._on_batch_file_converted)
            self.batch_conversion_thread.finished.connect(self._on_batch_conversion_finished)
            self.batch_conversion_thread.error.connect(self._on_batch_conversion_error)
            
            self.batch_conversion_thread.start()
            
        except Exception as e:
            if hasattr(self, 'video_result_text') and self.video_result_text:
                self.video_result_text.append(f"启动批量转换失败: {str(e)}")
            self._reset_batch_conversion_ui()
    
    def _on_batch_progress(self, current, total):
        """批量转换进度更新"""
        try:
            # 确保在主线程中执行UI更新
            if not self.thread() == QApplication.instance().thread():
                QTimer.singleShot(0, lambda: self._update_batch_progress_ui(current, total))
                return
            
            self._update_batch_progress_ui(current, total)
        except Exception as e:
            print(f"更新批量转换进度时出错: {e}")
    
    def _update_batch_progress_ui(self, current, total):
        """在主线程中更新批量转换进度UI"""
        try:
            if hasattr(self, 'video_progress_bar') and self.video_progress_bar:
                # 确保进度条有效且可见
                if not self.video_progress_bar.isVisible():
                    self.video_progress_bar.setVisible(True)
                
                # 安全地设置最大值和当前值
                if self.video_progress_bar.maximum() != total:
                    self.video_progress_bar.setMaximum(total)
                
                self.video_progress_bar.setValue(current)
                progress_percent = int((current / total) * 100) if total > 0 else 0
                self.video_progress_bar.setFormat(f"进度: {current}/{total} ({progress_percent}%)")
                
                # 强制刷新UI
                self.video_progress_bar.repaint()
                QApplication.processEvents()
        except Exception as e:
            print(f"更新批量转换进度UI时出错: {e}")
    
    def _on_batch_file_converted(self, file_path, success, message):
        """单个文件转换完成"""
        try:
            if hasattr(self, 'video_result_text') and self.video_result_text:
                file_name = os.path.basename(file_path)
                if success:
                    self.video_result_text.append(f"✓ {file_name} - 转换成功")
                else:
                    self.video_result_text.append(f"✗ {file_name} - 转换失败: {message}")
            
            # 滚动到底部
            if hasattr(self, 'video_result_text') and self.video_result_text:
                scrollbar = self.video_result_text.verticalScrollBar()
                scrollbar.setValue(scrollbar.maximum())
        except Exception as e:
            print(f"处理单个文件转换结果时出错: {e}")
    
    def _on_batch_conversion_finished(self, total_files, successful_files):
        """批量转换完成"""
        try:
            if hasattr(self, 'video_result_text') and self.video_result_text:
                self.video_result_text.append(f"\n批量转换完成! 总计: {total_files} 个文件，成功: {successful_files} 个")
            if hasattr(self, 'video_progress_bar') and self.video_progress_bar:
                self.video_progress_bar.setVisible(False)
            self._reset_batch_conversion_ui()
            
            # 清理线程
            if hasattr(self, 'batch_conversion_thread') and self.batch_conversion_thread:
                self.batch_conversion_thread.deleteLater()
                self.batch_conversion_thread = None
                
        except Exception as e:
            print(f"处理批量转换完成时出错: {e}")
    
    def _on_batch_conversion_error(self, error_message):
        """批量转换错误"""
        try:
            if hasattr(self, 'video_result_text') and self.video_result_text:
                self.video_result_text.append(f"\n批量转换出错: {error_message}")
            if hasattr(self, 'video_progress_bar') and self.video_progress_bar:
                self.video_progress_bar.setVisible(False)
            self._reset_batch_conversion_ui()
            
            # 清理线程
            if hasattr(self, 'batch_conversion_thread') and self.batch_conversion_thread:
                self.batch_conversion_thread.deleteLater()
                self.batch_conversion_thread = None
                
        except Exception as e:
            print(f"处理批量转换错误时出错: {e}")
    
    def _reset_batch_conversion_ui(self):
        """重置批量转换UI状态"""
        try:
            if hasattr(self, 'video_batch_convert_button') and self.video_batch_convert_button:
                self.video_batch_convert_button.setEnabled(True)
            if hasattr(self, 'video_folder_button') and self.video_folder_button:
                self.video_folder_button.setEnabled(True)
        except Exception as e:
            print(f"重置批量转换UI时出错: {e}")
    
    def _update_video_file_list(self):
        """更新视频文件列表显示"""
        try:
            # 检查必要的组件是否存在
            if not hasattr(self, 'video_file_list') or not self.video_file_list:
                return
            
            if not hasattr(self, 'video_path_label') or not self.video_path_label:
                self.video_file_list.setText("暂无选择文件")
                return
            
            # 获取当前选择的文件名
            current_text = self.video_path_label.text()
            if current_text and current_text != "未选择文件" and current_text.strip():
                self.video_file_list.setText(f"单个文件:\n{current_text}")
            else:
                self.video_file_list.setText("暂无选择文件")
        except Exception as e:
            print(f"更新视频文件列表时出错: {e}")
            # 设置默认文本，避免界面异常
            try:
                if hasattr(self, 'video_file_list') and self.video_file_list:
                    self.video_file_list.setText("暂无选择文件")
            except:
                pass

    def show_audio_ui(self):
        """显示音频转换界面"""
        main_layout = QVBoxLayout()
        main_layout.setSpacing(0)
        main_layout.setContentsMargins(15, 15, 15, 15)

        # 顶部标题区域 - 占1/10
        title_widget = QWidget()
        title_widget.setFixedHeight(60)
        title_layout = QVBoxLayout()
        title_layout.setContentsMargins(0, 0, 0, 0)
        title_widget.setLayout(title_layout)
        
        title = QLabel("音频转换")
        title.setStyleSheet(style_manager.get_interface_title_style())
        title.setAlignment(Qt.AlignCenter)
        title_layout.addWidget(title)
        main_layout.addWidget(title_widget)

        # 中间内容区域 - 占7/10
        middle_widget = QWidget()
        middle_layout = QHBoxLayout()
        middle_layout.setSpacing(10)
        middle_layout.setContentsMargins(0, 10, 0, 10)
        middle_widget.setLayout(middle_layout)
        
        # 左侧文件显示区域 - 占4/10
        left_widget = QWidget()
        left_widget.setStyleSheet(style_manager.get_left_widget_style())
        left_layout = QVBoxLayout()
        left_layout.setContentsMargins(10, 10, 10, 10)
        left_widget.setLayout(left_layout)
        
        # 文件列表标题
        file_list_title = QLabel("选择的文件")
        file_list_title.setStyleSheet(style_manager.get_file_list_title_style())
        left_layout.addWidget(file_list_title)
        
        # 文件列表显示区域
        self.audio_file_list = QTextEdit()
        self.audio_file_list.setReadOnly(True)
        self.audio_file_list.setStyleSheet(style_manager.get_file_list_style())
        self.audio_file_list.setPlaceholderText("暂无选择文件")
        left_layout.addWidget(self.audio_file_list)
        
        # 右侧标签页区域 - 占6/10
        right_widget = QWidget()
        right_layout = QVBoxLayout()
        right_layout.setContentsMargins(0, 0, 0, 0)
        right_widget.setLayout(right_layout)
        
        # 创建标签页
        self.audio_tab_widget = QTabWidget()
        self.audio_tab_widget.setStyleSheet(style_manager.get_tab_widget_style())
        
        # 单个转换标签页
        single_tab = QWidget()
        single_layout = QVBoxLayout()
        single_layout.setContentsMargins(15, 15, 15, 15)
        single_tab.setLayout(single_layout)
        
        # 文件选择和转换按钮
        file_widget, self.audio_path_label, self.audio_convert_button = self._create_file_selection_widget(
            "audio", "音频文件 (*.mp3 *.wav *.aac *.m4a *.flac *.ogg)"
        )
        single_layout.addWidget(file_widget)
        
        # 格式选择
        format_widget = QWidget()
        format_layout = QHBoxLayout()
        format_widget.setLayout(format_layout)
        
        format_label = QLabel("输出格式:")
        format_label.setStyleSheet("color: #A9B7C6; font-size: 14px; font-weight: bold;")
        self.audio_format_combo = QComboBox()
        self.audio_format_combo.addItems([
            "WAV (16.0kHz)", "MP3 (192kbps)", "AAC (128kbps)",
            "FLAC (无损)", "OGG (高质量)", "M4A (128kbps)"
        ])
        self.audio_format_combo.setStyleSheet(style_manager.get_combo_box_style())
        
        format_layout.addWidget(format_label)
        format_layout.addWidget(self.audio_format_combo)
        format_layout.addStretch()
        single_layout.addWidget(format_widget)
        single_layout.addStretch()
        
        # 批量转换标签页
        batch_tab = QWidget()
        batch_layout = QVBoxLayout()
        batch_layout.setContentsMargins(15, 15, 15, 15)
        batch_tab.setLayout(batch_layout)
        
        # 文件夹选择按钮
        folder_select_widget = QWidget()
        folder_select_layout = QHBoxLayout()
        folder_select_widget.setLayout(folder_select_layout)
        
        self.audio_folder_button = QPushButton("选择文件夹")
        self.audio_folder_button.setStyleSheet(style_manager.get_folder_button_style())
        
        self.audio_folder_path_label = QLabel("未选择文件夹")
        self.audio_folder_path_label.setStyleSheet(style_manager.get_path_label_style())
        
        folder_select_layout.addWidget(self.audio_folder_button)
        folder_select_layout.addWidget(self.audio_folder_path_label, 1)
        batch_layout.addWidget(folder_select_widget)
        
        # 批量转换按钮
        self.audio_batch_convert_button = QPushButton("开始批量转换")
        self.audio_batch_convert_button.setStyleSheet(style_manager.get_batch_convert_button_style())
        self.audio_batch_convert_button.setEnabled(False)
        batch_layout.addWidget(self.audio_batch_convert_button)
        batch_layout.addStretch()
        
        # 添加标签页
        self.audio_tab_widget.addTab(single_tab, "单个")
        self.audio_tab_widget.addTab(batch_tab, "批量")
        right_layout.addWidget(self.audio_tab_widget)
        
        # 设置左右比例 4:6
        middle_layout.addWidget(left_widget, 4)
        middle_layout.addWidget(right_widget, 6)
        main_layout.addWidget(middle_widget, 7)

        # 底部信息提示区域 - 占2/10
        bottom_widget = QWidget()
        bottom_widget.setFixedHeight(120)
        bottom_layout = QVBoxLayout()
        bottom_layout.setContentsMargins(0, 10, 0, 0)
        bottom_widget.setLayout(bottom_layout)
        
        # 进度条
        self.audio_progress_bar = QProgressBar()
        self.audio_progress_bar.setVisible(False)
        self.audio_progress_bar.setMinimum(0)
        self.audio_progress_bar.setMaximum(100)
        self.audio_progress_bar.setValue(0)
        self.audio_progress_bar.setTextVisible(True)
        bottom_layout.addWidget(self.audio_progress_bar)
        
        # 信息显示区域
        self.audio_result_text = QTextEdit()
        self.audio_result_text.setReadOnly(True)
        self.audio_result_text.setStyleSheet(style_manager.get_result_text_style())
        self.audio_result_text.setPlaceholderText("支持多种音频格式转换，输出高质量音频文件")
        self.audio_result_text.setMinimumHeight(100)  # 设置最小高度
        self.audio_result_text.setMaximumHeight(300)  # 设置最大高度，允许滚动查看更多内容
        bottom_layout.addWidget(self.audio_result_text)
        main_layout.addWidget(bottom_widget, 2)

        self.central_widget.setLayout(main_layout)
        
        # 绑定事件
        self.audio_convert_button.clicked.connect(lambda: self._start_conversion('audio'))
        self.audio_folder_button.clicked.connect(self._select_audio_folder)
        self.audio_batch_convert_button.clicked.connect(self._start_audio_batch_conversion)
        
        # 恢复之前的文件夹选择状态
        self._restore_audio_folder_state()
        
    def _restore_audio_folder_state(self):
        """恢复音频文件夹选择状态"""
        try:
            if hasattr(self, 'current_audio_folder') and self.current_audio_folder:
                if os.path.exists(self.current_audio_folder) and os.access(self.current_audio_folder, os.R_OK):
                    # 更新UI显示
                    folder_name = os.path.basename(self.current_audio_folder)
                    self.audio_folder_path_label.setText(f"已选择: {folder_name}")
                    
                    # 重新扫描音频文件
                    audio_extensions = ['.mp3', '.wav', '.aac', '.m4a', '.flac', '.ogg']
                    audio_files = []
                    
                    for file in os.listdir(self.current_audio_folder):
                        file_path = os.path.join(self.current_audio_folder, file)
                        if os.path.isfile(file_path):
                            _, ext = os.path.splitext(file)
                            if ext.lower() in audio_extensions:
                                audio_files.append(file)
                    
                    # 更新文件列表显示和按钮状态
                    if audio_files:
                        file_list_text = "\n".join([f"• {file}" for file in audio_files])
                        self.audio_file_list.setText(file_list_text)
                        self.audio_batch_convert_button.setEnabled(True)
                    else:
                        self.audio_file_list.setText("该文件夹中没有找到音频文件")
                        self.audio_batch_convert_button.setEnabled(False)
                else:
                    # 如果文件夹不存在或不可访问，清除状态
                    self.current_audio_folder = None
        except Exception as e:
            print(f"恢复音频文件夹状态时出错: {e}")
    
    def _select_audio_folder(self):
        """选择音频文件夹"""
        try:
            folder_path = QFileDialog.getExistingDirectory(
                self, "选择音频文件夹", "",
                QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks | QFileDialog.DontUseNativeDialog
            )
            
            if folder_path:
                # 检查文件夹是否存在且可读
                if not os.path.exists(folder_path) or not os.access(folder_path, os.R_OK):
                    QMessageBox.warning(self, "错误", "无法访问选择的文件夹")
                    return
                
                # 更新UI显示
                folder_name = os.path.basename(folder_path)
                self.audio_folder_path_label.setText(f"已选择: {folder_name}")
                
                # 扫描音频文件
                audio_extensions = ['.mp3', '.wav', '.aac', '.m4a', '.flac', '.ogg']
                audio_files = []
                
                for file in os.listdir(folder_path):
                    file_path = os.path.join(folder_path, file)
                    if os.path.isfile(file_path):
                        _, ext = os.path.splitext(file)
                        if ext.lower() in audio_extensions:
                            audio_files.append(file)
                
                # 更新文件列表显示
                if audio_files:
                    file_list_text = "\n".join([f"• {file}" for file in audio_files])
                    self.audio_file_list.setText(file_list_text)
                    self.audio_batch_convert_button.setEnabled(True)
                    
                    # 在结果区域显示扫描信息
                    self.audio_result_text.append(f"扫描完成: 在文件夹 '{folder_name}' 中找到 {len(audio_files)} 个音频文件")
                else:
                    self.audio_file_list.setText("该文件夹中没有找到音频文件")
                    self.audio_batch_convert_button.setEnabled(False)
                    self.audio_result_text.append(f"扫描完成: 在文件夹 '{folder_name}' 中没有找到音频文件")
                
                # 保存当前选择的文件夹路径
                self.current_audio_folder = folder_path
                
        except Exception as e:
            QMessageBox.critical(self, "错误", f"选择文件夹时发生错误: {str(e)}")
            self.audio_result_text.append(f"错误: 选择文件夹失败 - {str(e)}")
    
    def _start_audio_batch_conversion(self):
        """开始音频批量转换"""
        if not hasattr(self, 'current_audio_folder') or not self.current_audio_folder:
            QMessageBox.warning(self, "警告", "请先选择音频文件夹")
            return
        
        # 获取音频文件列表
        # 扩展支持的音频格式
        audio_extensions = [
            '.mp3', '.wav', '.aac', '.m4a', '.flac', '.ogg', '.wma', '.amr',
            '.3gp', '.mp4', '.mkv', '.avi', '.mov', '.wmv', '.webm', '.opus',
            '.ac3', '.dts', '.ape', '.wv', '.tta', '.ra', '.rm', '.au', '.aiff'
        ]
        audio_files = []
        invalid_files = []
        unknown_files = []
        
        try:
            # 显示检测进度
            self.audio_result_text.clear()
            self.audio_result_text.append("正在检测音频文件...")
            
            for file in os.listdir(self.current_audio_folder):
                file_path = os.path.join(self.current_audio_folder, file)
                if os.path.isfile(file_path):
                    _, ext = os.path.splitext(file)
                    
                    # 首先检查是否为已知音频扩展名
                    if ext.lower() in audio_extensions:
                        # 使用ffprobe验证文件是否为有效音频
                        if self.converter.is_valid_audio_file(file_path):
                            audio_files.append(file_path)
                        else:
                            invalid_files.append(file)
                            self.audio_result_text.append(f"⚠️ 跳过无效音频文件: {file}")
                    else:
                        # 对于未知扩展名的文件，也尝试用ffprobe检测
                        if ext.lower() not in ['.txt', '.log', '.ini', '.cfg', '.xml', '.json', '.md', '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.zip', '.rar', '.7z', '.tar', '.gz']:
                            if self.converter.is_valid_audio_file(file_path):
                                audio_files.append(file_path)
                                self.audio_result_text.append(f"✓ 发现音频文件: {file} (未知扩展名)")
                            else:
                                unknown_files.append(file)
            
            # 显示检测结果摘要
            summary_parts = [f"发现 {len(audio_files)} 个有效音频文件"]
            if invalid_files:
                summary_parts.append(f"{len(invalid_files)} 个无效文件")
            if unknown_files:
                summary_parts.append(f"{len(unknown_files)} 个未知格式文件")
            
            self.audio_result_text.append(f"\n检测完成: {', '.join(summary_parts)}")
            
            if not audio_files:
                if invalid_files:
                    QMessageBox.warning(self, "警告", f"选择的文件夹中没有有效的音频文件\n发现 {len(invalid_files)} 个无效文件，请检查文件格式")
                else:
                    QMessageBox.warning(self, "警告", "选择的文件夹中没有音频文件")
                return
            
            # 显示进度条
            self.audio_progress_bar.setVisible(True)
            self.audio_progress_bar.setMaximum(len(audio_files))
            self.audio_progress_bar.setValue(0)
            
            # 添加转换开始信息
            self.audio_result_text.append(f"\n开始批量转换 {len(audio_files)} 个音频文件...")
            
            # 获取输出格式
            format_map = {
                "WAV (16.0kHz)": "wav",
                "MP3 (192kbps)": "mp3",
                "AAC (128kbps)": "aac",
                "FLAC (无损)": "flac",
                "OGG (高质量)": "ogg",
                "M4A (128kbps)": "m4a"
            }
            output_format = format_map.get(self.audio_format_combo.currentText(), "wav")
            
            # 创建并启动批量转换线程
            self.audio_batch_thread = BatchConversionThread(audio_files, self.converter, 'audio', output_format)
            self.audio_batch_thread.progress_updated.connect(self._on_audio_batch_progress)
            self.audio_batch_thread.file_converted.connect(self._on_audio_file_converted)
            self.audio_batch_thread.finished.connect(self._on_audio_batch_finished)
            self.audio_batch_thread.error.connect(self._on_audio_batch_error)
            
            # 禁用批量转换按钮
            self.audio_batch_convert_button.setEnabled(False)
            self.audio_batch_convert_button.setText("转换中...")
            
            self.audio_batch_thread.start()
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"启动批量转换时发生错误: {str(e)}")
            self.audio_result_text.append(f"错误: 批量转换启动失败 - {str(e)}")
    
    def _on_audio_batch_progress(self, value):
        """音频批量转换进度更新"""
        try:
            # 确保在主线程中执行UI更新
            if not self.thread() == QApplication.instance().thread():
                QTimer.singleShot(0, lambda: self._update_audio_batch_progress_ui(value))
                return
            
            self._update_audio_batch_progress_ui(value)
        except Exception as e:
            print(f"更新音频批量转换进度时出错: {e}")
    
    def _update_audio_batch_progress_ui(self, value):
        """在主线程中更新音频批量转换进度UI"""
        try:
            if hasattr(self, 'audio_progress_bar') and self.audio_progress_bar:
                # 确保进度条有效且可见
                if not self.audio_progress_bar.isVisible():
                    self.audio_progress_bar.setVisible(True)
                    # 确保进度条范围正确设置
                    self.audio_progress_bar.setMinimum(0)
                    self.audio_progress_bar.setMaximum(100)
                
                self.audio_progress_bar.setValue(value)
                
                # 强制刷新UI
                self.audio_progress_bar.repaint()
                QApplication.processEvents()
        except Exception as e:
            print(f"更新音频批量转换进度UI时出错: {e}")
    
    def _on_audio_file_converted(self, file_path, success, message):
        """音频文件转换完成回调"""
        try:
            if hasattr(self, 'audio_result_text') and self.audio_result_text:
                filename = os.path.basename(file_path)
                if success:
                    self.audio_result_text.append(f"✓ 转换成功: {filename}")
                else:
                    self.audio_result_text.append(f"✗ 转换失败: {filename} - {message}")
                
                # 滚动到底部
                cursor = self.audio_result_text.textCursor()
                cursor.movePosition(cursor.End)
                self.audio_result_text.setTextCursor(cursor)
        except Exception as e:
            print(f"更新音频转换进度时出错: {e}")
    
    def _on_audio_batch_finished(self, total_files, successful_files):
        """音频批量转换完成回调"""
        try:
            if hasattr(self, 'audio_progress_bar') and self.audio_progress_bar:
                self.audio_progress_bar.setVisible(False)
            if hasattr(self, 'audio_batch_convert_button') and self.audio_batch_convert_button:
                self.audio_batch_convert_button.setEnabled(True)
                self.audio_batch_convert_button.setText("开始批量转换")
            
            if hasattr(self, 'audio_result_text') and self.audio_result_text:
                self.audio_result_text.append(f"\n批量转换完成! 总计: {total_files} 个文件，成功: {successful_files} 个")
                
                # 滚动到底部
                cursor = self.audio_result_text.textCursor()
                cursor.movePosition(cursor.End)
                self.audio_result_text.setTextCursor(cursor)
        except Exception as e:
            print(f"更新音频批量转换完成状态时出错: {e}")
    
    def _on_audio_batch_error(self, error_message):
        """音频批量转换错误回调"""
        try:
            if hasattr(self, 'audio_progress_bar') and self.audio_progress_bar:
                self.audio_progress_bar.setVisible(False)
            if hasattr(self, 'audio_batch_convert_button') and self.audio_batch_convert_button:
                self.audio_batch_convert_button.setEnabled(True)
                self.audio_batch_convert_button.setText("开始批量转换")
            
            if hasattr(self, 'audio_result_text') and self.audio_result_text:
                self.audio_result_text.append(f"\n批量转换出错: {error_message}")
            
            QMessageBox.critical(self, "错误", f"批量转换失败: {error_message}")
        except Exception as e:
            print(f"处理音频批量转换错误时出错: {e}")
    
    def _update_audio_file_list(self):
        """更新音频文件列表显示"""
        try:
            # 检查必要的组件是否存在
            if not hasattr(self, 'audio_file_list') or not self.audio_file_list:
                return
            
            if not hasattr(self, 'audio_path_label') or not self.audio_path_label:
                self.audio_file_list.setText("暂无选择文件")
                return
            
            # 获取当前选择的文件名
            current_text = self.audio_path_label.text()
            if current_text and current_text != "未选择音频文件" and current_text.strip():
                self.audio_file_list.setText(f"单个文件:\n{current_text}")
            else:
                self.audio_file_list.setText("暂无选择文件")
        except Exception as e:
            print(f"更新音频文件列表时出错: {e}")
            # 设置默认文本，避免界面异常
            try:
                if hasattr(self, 'audio_file_list') and self.audio_file_list:
                    self.audio_file_list.setText("暂无选择文件")
            except:
                pass
    
    def _update_image_file_list(self):
        """更新图片文件列表显示"""
        try:
            # 检查必要的组件是否存在
            if not hasattr(self, 'image_file_list') or not self.image_file_list:
                return
            
            if not hasattr(self, 'image_path_label') or not self.image_path_label:
                self.image_file_list.setText("暂无选择文件")
                return
            
            # 获取当前选择的文件名
            current_text = self.image_path_label.text()
            if current_text and current_text != "未选择图片文件" and current_text.strip():
                self.image_file_list.setText(f"单个文件:\n{current_text}")
            else:
                self.image_file_list.setText("暂无选择文件")
        except Exception as e:
            print(f"更新图片文件列表时出错: {e}")
            # 设置默认文本，避免界面异常
            try:
                if hasattr(self, 'image_file_list') and self.image_file_list:
                    self.image_file_list.setText("暂无选择文件")
            except:
                pass

    def show_image_ui(self):
        """显示图片转换界面"""
        main_layout = QVBoxLayout()
        main_layout.setSpacing(0)
        main_layout.setContentsMargins(15, 15, 15, 15)

        # 顶部标题区域 - 占1/10
        title_widget = QWidget()
        title_widget.setFixedHeight(60)
        title_layout = QVBoxLayout()
        title_layout.setContentsMargins(0, 0, 0, 0)
        title_widget.setLayout(title_layout)
        
        title = QLabel("图片转换")
        title.setStyleSheet(style_manager.get_interface_title_style())
        title.setAlignment(Qt.AlignCenter)
        title_layout.addWidget(title)
        main_layout.addWidget(title_widget)

        # 中间内容区域 - 占7/10
        middle_widget = QWidget()
        middle_layout = QHBoxLayout()
        middle_layout.setSpacing(10)
        middle_layout.setContentsMargins(0, 10, 0, 10)
        middle_widget.setLayout(middle_layout)
        
        # 左侧文件显示区域 - 占4/10
        left_widget = QWidget()
        left_widget.setStyleSheet(style_manager.get_left_widget_style())
        left_layout = QVBoxLayout()
        left_layout.setContentsMargins(10, 10, 10, 10)
        left_widget.setLayout(left_layout)
        
        # 文件列表标题
        file_list_title = QLabel("选择的文件")
        file_list_title.setStyleSheet(style_manager.get_file_list_title_style())
        left_layout.addWidget(file_list_title)
        
        # 文件列表显示区域
        self.image_file_list = QTextEdit()
        self.image_file_list.setReadOnly(True)
        self.image_file_list.setStyleSheet(style_manager.get_file_list_style())
        self.image_file_list.setPlaceholderText("暂无选择文件")
        left_layout.addWidget(self.image_file_list)
        
        # 右侧标签页区域 - 占6/10
        right_widget = QWidget()
        right_layout = QVBoxLayout()
        right_layout.setContentsMargins(0, 0, 0, 0)
        right_widget.setLayout(right_layout)
        
        # 创建标签页
        self.image_tab_widget = QTabWidget()
        self.image_tab_widget.setStyleSheet(style_manager.get_tab_widget_style())
        
        # 单个转换标签页
        single_tab = QWidget()
        single_layout = QVBoxLayout()
        single_layout.setContentsMargins(15, 15, 15, 15)
        single_tab.setLayout(single_layout)
        
        # 文件选择和转换按钮
        file_widget, self.image_path_label, self.image_convert_button = self._create_file_selection_widget(
            "image", "图片文件 (*.jpg *.jpeg *.png *.bmp *.gif *.tiff)"
        )
        single_layout.addWidget(file_widget)
        
        # 格式选择
        format_widget = QWidget()
        format_layout = QHBoxLayout()
        format_widget.setLayout(format_layout)
        
        format_label = QLabel("输出格式:")
        format_label.setStyleSheet("color: #A9B7C6; font-size: 14px; font-weight: bold;")
        self.image_format_combo = QComboBox()
        self.image_format_combo.addItems(["JPG", "PNG", "BMP"])
        self.image_format_combo.setStyleSheet(style_manager.get_combo_box_style())
        
        format_layout.addWidget(format_label)
        format_layout.addWidget(self.image_format_combo)
        format_layout.addStretch()
        single_layout.addWidget(format_widget)
        single_layout.addStretch()
        
        # 批量转换标签页
        batch_tab = QWidget()
        batch_layout = QVBoxLayout()
        batch_layout.setContentsMargins(15, 15, 15, 15)
        batch_tab.setLayout(batch_layout)
        
        # 文件夹选择按钮
        folder_select_widget = QWidget()
        folder_select_layout = QHBoxLayout()
        folder_select_widget.setLayout(folder_select_layout)
        
        self.image_folder_button = QPushButton("选择文件夹")
        self.image_folder_button.setStyleSheet(style_manager.get_folder_button_style())
        
        self.image_folder_path_label = QLabel("未选择文件夹")
        self.image_folder_path_label.setStyleSheet(style_manager.get_path_label_style())
        
        folder_select_layout.addWidget(self.image_folder_button)
        folder_select_layout.addWidget(self.image_folder_path_label, 1)
        batch_layout.addWidget(folder_select_widget)
        
        # 批量转换按钮
        self.image_batch_convert_button = QPushButton("开始批量转换")
        self.image_batch_convert_button.setStyleSheet(style_manager.get_batch_convert_button_style())
        self.image_batch_convert_button.setEnabled(False)
        batch_layout.addWidget(self.image_batch_convert_button)
        batch_layout.addStretch()
        
        # 添加标签页
        self.image_tab_widget.addTab(single_tab, "单个")
        self.image_tab_widget.addTab(batch_tab, "批量")
        right_layout.addWidget(self.image_tab_widget)
        
        # 设置左右比例 4:6
        middle_layout.addWidget(left_widget, 4)
        middle_layout.addWidget(right_widget, 6)
        main_layout.addWidget(middle_widget, 7)

        # 底部信息提示区域 - 占2/10
        bottom_widget = QWidget()
        bottom_widget.setFixedHeight(120)
        bottom_layout = QVBoxLayout()
        bottom_layout.setContentsMargins(0, 10, 0, 0)
        bottom_widget.setLayout(bottom_layout)
        
        # 进度条
        self.image_progress_bar = QProgressBar()
        self.image_progress_bar.setVisible(False)
        self.image_progress_bar.setMinimum(0)
        self.image_progress_bar.setMaximum(100)
        self.image_progress_bar.setValue(0)
        self.image_progress_bar.setTextVisible(True)
        bottom_layout.addWidget(self.image_progress_bar)
        
        # 信息显示区域
        self.image_result_text = QTextEdit()
        self.image_result_text.setReadOnly(True)
        self.image_result_text.setStyleSheet(style_manager.get_result_text_style())
        self.image_result_text.setPlaceholderText("支持多种图片格式转换，输出为1080x1920分辨率")
        self.image_result_text.setMinimumHeight(100)  # 设置最小高度
        self.image_result_text.setMaximumHeight(300)  # 设置最大高度，允许滚动查看更多内容
        bottom_layout.addWidget(self.image_result_text)
        main_layout.addWidget(bottom_widget, 2)

        self.central_widget.setLayout(main_layout)
        
        # 绑定事件
        self.image_convert_button.clicked.connect(lambda: self._start_conversion('image'))
        self.image_folder_button.clicked.connect(self._select_image_folder)
        self.image_batch_convert_button.clicked.connect(self._start_image_batch_conversion)
        
        # 恢复之前的文件夹选择状态
        self._restore_image_folder_state()

    def _start_conversion(self, media_type):
        """开始转换"""
        # 检查是否有转换正在进行
        if self.conversion_thread and self.conversion_thread.isRunning():
            QMessageBox.warning(self, "警告", "转换正在进行中，请等待完成后再开始新的转换。")
            return
            
        file_path = self.current_file_paths.get(media_type)
        if not file_path:
            # 媒体类型中英文映射
            type_map = {
                'video': '视频',
                'audio': '音频', 
                'image': '图片'
            }
            display_name = type_map.get(media_type, media_type)
            QMessageBox.warning(self, "警告", f"请先选择一个{display_name}文件。")
            return
            
        # 检查文件是否存在
        if not os.path.exists(file_path):
            QMessageBox.warning(self, "警告", f"文件不存在: {file_path}")
            return

        # 准备转换参数
        kwargs = {}
        try:
            if media_type == 'audio':
                if hasattr(self, 'audio_format_combo'):
                    format_map = {
                        "WAV (16.0kHz)": "wav",
                        "MP3 (192kbps)": "mp3",
                        "AAC (128kbps)": "aac",
                        "FLAC (无损)": "flac",
                        "OGG (高质量)": "ogg",
                        "M4A (128kbps)": "m4a"
                    }
                    kwargs['output_format'] = format_map[self.audio_format_combo.currentText()]
            elif media_type == 'image':
                if hasattr(self, 'image_format_combo'):
                    kwargs['output_format'] = self.image_format_combo.currentText().lower()
        except Exception as e:
            QMessageBox.warning(self, "警告", f"参数设置错误: {str(e)}")
            return

        # 重置并显示对应的进度条
        self._reset_progress_for_media_type(media_type)
            
        # 更新文件列表显示（仅对音频）
        if media_type == 'audio' and hasattr(self, 'audio_file_list'):
            filename = os.path.basename(file_path)
            self.audio_file_list.setText(f"• {filename}")
        
        # 创建并启动转换线程
        try:
            self.conversion_thread = ConversionThread(
                self.converter, media_type, file_path, **kwargs
            )
            self.conversion_thread.finished.connect(self._on_conversion_finished)
            self.conversion_thread.error.connect(self._on_conversion_error)
            self.conversion_thread.progress.connect(self._on_conversion_progress)
            self.conversion_thread.start()
        except Exception as e:
            # 隐藏进度条
            if hasattr(self, 'video_progress_bar') and self.video_progress_bar:
                self.video_progress_bar.setVisible(False)
            elif hasattr(self, 'audio_progress_bar') and self.audio_progress_bar:
                self.audio_progress_bar.setVisible(False)
            elif hasattr(self, 'image_progress_bar') and self.image_progress_bar:
                self.image_progress_bar.setVisible(False)
            elif hasattr(self, 'progress_bar') and self.progress_bar:
                self.progress_bar.setVisible(False)
            QMessageBox.critical(self, "错误", f"启动转换线程失败: {str(e)}")

    def _on_conversion_finished(self, output_file):
        """转换完成"""
        try:
            # 先将进度条设置为100%
            if hasattr(self, 'progress_bar') and self.progress_bar and not self._is_widget_deleted(self.progress_bar) and self.progress_bar.isVisible():
                self.progress_bar.setValue(100)
            if hasattr(self, 'video_progress_bar') and self.video_progress_bar and not self._is_widget_deleted(self.video_progress_bar) and self.video_progress_bar.isVisible():
                self.video_progress_bar.setValue(100)
            if hasattr(self, 'audio_progress_bar') and self.audio_progress_bar and not self._is_widget_deleted(self.audio_progress_bar) and self.audio_progress_bar.isVisible():
                self.audio_progress_bar.setValue(100)
            if hasattr(self, 'image_progress_bar') and self.image_progress_bar and not self._is_widget_deleted(self.image_progress_bar) and self.image_progress_bar.isVisible():
                self.image_progress_bar.setValue(100)
            
            # 短暂延迟后隐藏进度条
            QTimer.singleShot(1000, self._hide_progress_bars)
            
            # 显示转换结果
            success_message = f"转换成功！\n输出路径：{output_file}"
            if hasattr(self, 'video_progress_bar') and self.video_progress_bar and not self._is_widget_deleted(self.video_progress_bar) and self.video_progress_bar.isVisible() and hasattr(self, 'video_result_text') and self.video_result_text and not self._is_widget_deleted(self.video_result_text):
                self.video_result_text.setText(success_message)
            elif hasattr(self, 'audio_progress_bar') and self.audio_progress_bar and not self._is_widget_deleted(self.audio_progress_bar) and self.audio_progress_bar.isVisible() and hasattr(self, 'audio_result_text') and self.audio_result_text and not self._is_widget_deleted(self.audio_result_text):
                self.audio_result_text.setText(success_message)
            elif hasattr(self, 'image_progress_bar') and self.image_progress_bar and not self._is_widget_deleted(self.image_progress_bar) and self.image_progress_bar.isVisible() and hasattr(self, 'image_result_text') and self.image_result_text and not self._is_widget_deleted(self.image_result_text):
                self.image_result_text.setText(success_message)
            elif hasattr(self, 'result_text') and self.result_text and not self._is_widget_deleted(self.result_text):
                self.result_text.setText(success_message)
            
            QMessageBox.information(self, "成功", "转换完成！")
        except Exception as e:
            print(f"处理转换完成事件时出错: {e}")
        finally:
            # 清理线程引用
            if self.conversion_thread:
                self.conversion_thread.deleteLater()
                self.conversion_thread = None
    
    def _hide_progress_bars(self):
        """隐藏所有进度条"""
        try:
            # 确保在主线程中执行UI更新
            if not self.thread() == QApplication.instance().thread():
                QTimer.singleShot(0, self._hide_progress_bars_ui)
                return
            
            self._hide_progress_bars_ui()
        except Exception as e:
            print(f"隐藏进度条时出错: {e}")
    
    def _hide_progress_bars_ui(self):
        """在主线程中隐藏所有进度条"""
        try:
            progress_bars = []
            
            # 只隐藏当前活跃的进度条，避免状态混乱
            media_type, active_progress_bar, _ = self._get_active_progress_components()
            if active_progress_bar and not self._is_widget_deleted(active_progress_bar):
                progress_bars.append(active_progress_bar)
            else:
                # 如果没有活跃的进度条，隐藏所有可能的进度条
                if hasattr(self, 'progress_bar') and self.progress_bar and not self._is_widget_deleted(self.progress_bar):
                    progress_bars.append(self.progress_bar)
                if hasattr(self, 'video_progress_bar') and self.video_progress_bar and not self._is_widget_deleted(self.video_progress_bar):
                    progress_bars.append(self.video_progress_bar)
                if hasattr(self, 'audio_progress_bar') and self.audio_progress_bar and not self._is_widget_deleted(self.audio_progress_bar):
                    progress_bars.append(self.audio_progress_bar)
                if hasattr(self, 'image_progress_bar') and self.image_progress_bar and not self._is_widget_deleted(self.image_progress_bar):
                    progress_bars.append(self.image_progress_bar)
            
            for progress_bar in progress_bars:
                if progress_bar and not self._is_widget_deleted(progress_bar) and progress_bar.isVisible():
                    progress_bar.setVisible(False)
                    progress_bar.setValue(0)
                    progress_bar.repaint()
            
            # 强制刷新UI
            QApplication.processEvents()
        except Exception as e:
            print(f"隐藏进度条UI时出错: {e}")

    def _on_conversion_error(self, error_msg):
        """转换出错"""
        try:
            # 隐藏进度条
            self._hide_progress_bars()
            
            # 显示错误信息
            error_message = f"转换失败：\n{error_msg}"
            if hasattr(self, 'video_result_text') and self.video_result_text:
                self.video_result_text.setText(error_message)
            elif hasattr(self, 'audio_result_text') and self.audio_result_text:
                self.audio_result_text.setText(error_message)
            elif hasattr(self, 'image_result_text') and self.image_result_text:
                self.image_result_text.setText(error_message)
            elif hasattr(self, 'result_text') and self.result_text:
                self.result_text.setText(error_message)
            
            QMessageBox.critical(self, "错误", f"转换失败：\n{error_msg}")
        except Exception as e:
            print(f"处理转换错误事件时出错: {e}")
        finally:
            # 清理线程引用
            if self.conversion_thread:
                self.conversion_thread.deleteLater()
                self.conversion_thread = None

    def _on_conversion_progress(self, message):
        """转换进度更新"""
        try:
            # 确保在主线程中执行UI更新
            if not self.thread() == QApplication.instance().thread():
                # 如果不在主线程，使用QTimer.singleShot确保在主线程执行
                QTimer.singleShot(0, lambda: self._update_progress_ui(message))
                return
            
            self._update_progress_ui(message)
        except Exception as e:
            print(f"更新转换进度时出错: {e}")
    
    def _update_progress_ui(self, message):
        """在主线程中更新进度UI"""
        try:
            # 根据消息更新进度条
            progress_value = self._get_progress_value(message)
            
            # 确定当前活跃的媒体类型和对应的进度条
            media_type, progress_bar, result_text = self._get_active_progress_components()
            
            if progress_bar and not self._is_widget_deleted(progress_bar):
                # 确保进度条正确初始化和显示
                if not progress_bar.isVisible():
                    progress_bar.setVisible(True)
                    progress_bar.setMinimum(0)
                    progress_bar.setMaximum(100)
                    progress_bar.setValue(0)
                
                progress_bar.setValue(progress_value)
                # 强制刷新UI
                progress_bar.repaint()
                QApplication.processEvents()
            
            if result_text and not self._is_widget_deleted(result_text):
                result_text.setText(message)
                result_text.repaint()
                
        except Exception as e:
            print(f"更新进度UI时出错: {e}")
    
    def _is_widget_deleted(self, widget):
        """检查Qt widget是否已被删除"""
        try:
            # 尝试访问widget的一个基本属性
            # 如果对象已被删除，这会抛出RuntimeError
            widget.isVisible()
            return False
        except RuntimeError:
            # Qt对象已被删除
            return True
        except Exception:
            # 其他异常，假设对象仍然有效
            return False
    
    def _get_progress_value(self, message):
        """根据消息获取进度值"""
        if "开始转换" in message:
            return 10
        elif "正在处理" in message:
            return 30
        elif "正在读取图片" in message:
            return 40
        elif "图片处理完成" in message:
            return 70
        elif "正在读取音频" in message:
            return 40
        elif "音频处理完成" in message:
            return 70
        elif "正在读取视频" in message:
            return 40
        elif "视频处理完成" in message:
            return 70
        elif "即将完成" in message:
            return 80
        elif "转换完成" in message:
            return 100
        return 0
    
    def _get_active_progress_components(self):
        """获取当前活跃的进度条和结果文本组件"""
        # 视频转换
        if hasattr(self, 'video_progress_bar') and self.video_progress_bar and self.video_progress_bar.isVisible():
            result_text = getattr(self, 'video_result_text', None)
            return 'video', self.video_progress_bar, result_text
        
        # 音频转换
        elif hasattr(self, 'audio_progress_bar') and self.audio_progress_bar and self.audio_progress_bar.isVisible():
            result_text = getattr(self, 'audio_result_text', None)
            return 'audio', self.audio_progress_bar, result_text
        
        # 图片转换
        elif hasattr(self, 'image_progress_bar') and self.image_progress_bar and self.image_progress_bar.isVisible():
            result_text = getattr(self, 'image_result_text', None)
            return 'image', self.image_progress_bar, result_text
        
        # 通用进度条（向后兼容）
        elif hasattr(self, 'progress_bar') and self.progress_bar and self.progress_bar.isVisible():
            result_text = getattr(self, 'result_text', None)
            return 'general', self.progress_bar, result_text
        
        return None, None, None
    
    def _reset_progress_for_media_type(self, media_type):
        """为指定媒体类型重置进度条和结果文本"""
        try:
            # 隐藏所有其他进度条，确保状态不混乱
            self._hide_all_progress_bars_except(media_type)
            
            # 显示并重置对应的进度条
            if media_type == 'video' and hasattr(self, 'video_progress_bar') and self.video_progress_bar and not self._is_widget_deleted(self.video_progress_bar):
                self.video_progress_bar.setVisible(True)
                self.video_progress_bar.setMinimum(0)
                self.video_progress_bar.setMaximum(100)
                self.video_progress_bar.setValue(0)
                if hasattr(self, 'video_result_text') and self.video_result_text and not self._is_widget_deleted(self.video_result_text):
                    self.video_result_text.clear()
            elif media_type == 'audio' and hasattr(self, 'audio_progress_bar') and self.audio_progress_bar and not self._is_widget_deleted(self.audio_progress_bar):
                self.audio_progress_bar.setVisible(True)
                self.audio_progress_bar.setMinimum(0)
                self.audio_progress_bar.setMaximum(100)
                self.audio_progress_bar.setValue(0)
                if hasattr(self, 'audio_result_text') and self.audio_result_text and not self._is_widget_deleted(self.audio_result_text):
                    self.audio_result_text.clear()
            elif media_type == 'image' and hasattr(self, 'image_progress_bar') and self.image_progress_bar and not self._is_widget_deleted(self.image_progress_bar):
                self.image_progress_bar.setVisible(True)
                self.image_progress_bar.setMinimum(0)
                self.image_progress_bar.setMaximum(100)
                self.image_progress_bar.setValue(0)
                if hasattr(self, 'image_result_text') and self.image_result_text and not self._is_widget_deleted(self.image_result_text):
                    self.image_result_text.clear()
            else:
                # 使用通用进度条
                if hasattr(self, 'progress_bar') and self.progress_bar:
                    self.progress_bar.setVisible(True)
                    self.progress_bar.setRange(0, 100)
                    self.progress_bar.setValue(0)
                if hasattr(self, 'result_text') and self.result_text:
                    self.result_text.clear()
        except Exception as e:
            print(f"重置进度条时出错: {e}")
    
    def _hide_all_progress_bars_except(self, active_media_type):
        """隐藏除指定媒体类型外的所有进度条"""
        try:
            if active_media_type != 'video' and hasattr(self, 'video_progress_bar') and self.video_progress_bar and not self._is_widget_deleted(self.video_progress_bar):
                self.video_progress_bar.setVisible(False)
            if active_media_type != 'audio' and hasattr(self, 'audio_progress_bar') and self.audio_progress_bar and not self._is_widget_deleted(self.audio_progress_bar):
                self.audio_progress_bar.setVisible(False)
            if active_media_type != 'image' and hasattr(self, 'image_progress_bar') and self.image_progress_bar and not self._is_widget_deleted(self.image_progress_bar):
                self.image_progress_bar.setVisible(False)
            if active_media_type not in ['video', 'audio', 'image'] and hasattr(self, 'progress_bar') and self.progress_bar and not self._is_widget_deleted(self.progress_bar):
                # 只有在使用通用进度条时才保持可见
                pass
            elif hasattr(self, 'progress_bar') and self.progress_bar and not self._is_widget_deleted(self.progress_bar):
                self.progress_bar.setVisible(False)
        except Exception as e:
            print(f"隐藏进度条时出错: {e}")
 
    def show_about_info(self):
        """显示关于信息"""
        layout = QVBoxLayout()
        layout.setAlignment(Qt.AlignCenter)
        layout.setSpacing(15)
        layout.setContentsMargins(50, 50, 50, 50)

        title_label = QLabel("多媒体转换工具")
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setStyleSheet(style_manager.get_title_label_style())

        version_label = QLabel(f"版本 {app_version}")
        version_label.setAlignment(Qt.AlignCenter)
        version_label.setStyleSheet(style_manager.get_version_label_style())

        author_label = QLabel("作者：Jake")
        author_label.setAlignment(Qt.AlignCenter)
        author_label.setStyleSheet(style_manager.get_author_label_style())

        date_label = QLabel("开发时间：2025年06月")
        date_label.setAlignment(Qt.AlignCenter)
        date_label.setStyleSheet(style_manager.get_date_label_style())
        
        description_label = QLabel("一个功能强大的多媒体格式转换工具\n支持视频、音频、图片的批量转换和处理")
        description_label.setAlignment(Qt.AlignCenter)
        description_label.setStyleSheet(style_manager.get_description_label_style())
        description_label.setWordWrap(True)

        layout.addWidget(title_label)
        layout.addWidget(version_label)
        layout.addWidget(author_label)
        layout.addWidget(date_label)
        layout.addWidget(description_label)

        self.central_widget.setLayout(layout)

    def show_player_ui(self):
        """显示播放器界面"""
        
        # 创建主水平分割器
        main_splitter = QSplitter(Qt.Horizontal)
        main_splitter.setStyleSheet("""
            QSplitter::handle {
                background-color: #3C3C3C;
                width: 3px;
            }
            QSplitter::handle:hover {
                background-color: #5C5C5C;
            }
        """)
        
        # 左侧：视频/音频播放器区域
        left_widget = QWidget()
        left_widget.setStyleSheet("""
            QWidget {
                background-color: #2B2B2B;
                border: 1px solid #3C3C3C;
                border-radius: 5px;
            }
        """)
        left_layout = QVBoxLayout()
        left_layout.setContentsMargins(10, 10, 10, 10)
        left_widget.setLayout(left_layout)
        
        # 移除播放器标题，让播放器区域更大
        
        # 播放器显示区域（占位）
        player_display = QLabel("点击播放器菜单选择媒体文件开始播放\n\n支持视频和音频播放\n窗口大小自适应")
        player_display.setAlignment(Qt.AlignCenter)
        player_display.setStyleSheet("""
            QLabel {
                color: #808080;
                font-size: 16px;
                background-color: #1E1E1E;
                border: 2px dashed #3C3C3C;
                border-radius: 8px;
                padding: 30px;
                min-height: 300px;
            }
        """)
        left_layout.addWidget(player_display, 1)
        
        # 播放控制按钮
        control_widget = QWidget()
        control_layout = QHBoxLayout()
        control_layout.setContentsMargins(0, 10, 0, 0)
        control_widget.setLayout(control_layout)
        
        # 创建带图标的按钮
        play_button = QPushButton("播放")
        pause_button = QPushButton("暂停")
        stop_button = QPushButton("停止")
        
        # 设置按钮图标
        play_icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'play.png')
        pause_icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'pause.png')
        stop_icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'stop.png')
        
        if os.path.exists(play_icon_path):
            play_button.setIcon(QIcon(play_icon_path))
        if os.path.exists(pause_icon_path):
            pause_button.setIcon(QIcon(pause_icon_path))
        if os.path.exists(stop_icon_path):
            stop_button.setIcon(QIcon(stop_icon_path))
        
        button_style = """
            QPushButton {
                background-color: #4A4A4A;
                color: #A9B7C6;
                border: 1px solid #5C5C5C;
                border-radius: 3px;
                padding: 8px 16px;
                font-size: 12px;
            }
            QPushButton:hover {
                background-color: #5A5A5A;
            }
            QPushButton:pressed {
                background-color: #3A3A3A;
            }
        """
        
        play_button.setStyleSheet(button_style)
        pause_button.setStyleSheet(button_style)
        stop_button.setStyleSheet(button_style)
        
        control_layout.addWidget(play_button)
        control_layout.addWidget(pause_button)
        control_layout.addWidget(stop_button)
        control_layout.addStretch()
        
        left_layout.addWidget(control_widget)
        
        # 右侧：垂直分割器
        right_splitter = QSplitter(Qt.Vertical)
        right_splitter.setStyleSheet("""
            QSplitter::handle {
                background-color: #3C3C3C;
                height: 3px;
            }
            QSplitter::handle:hover {
                background-color: #5C5C5C;
            }
        """)
        
        # 右上：收藏列表
        favorites_widget = QWidget()
        favorites_widget.setStyleSheet("""
            QWidget {
                background-color: #2B2B2B;
                border: 1px solid #3C3C3C;
                border-radius: 5px;
            }
        """)
        favorites_layout = QVBoxLayout()
        favorites_layout.setContentsMargins(10, 10, 10, 10)
        favorites_widget.setLayout(favorites_layout)
        
        favorites_title = QLabel("收藏列表")
        favorites_title.setStyleSheet("""
            QLabel {
                color: #A9B7C6;
                font-size: 14px;
                font-weight: bold;
                background-color: transparent;
                border: none;
                padding: 5px;
            }
        """)
        favorites_layout.addWidget(favorites_title)
        
        favorites_list = QListWidget()
        favorites_list.setStyleSheet("""
            QListWidget {
                background-color: #1E1E1E;
                color: #A9B7C6;
                border: 1px solid #3C3C3C;
                border-radius: 3px;
                padding: 5px;
                font-size: 12px;
                outline: none;
            }
            QListWidget::item {
                padding: 8px;
                border-bottom: 1px solid #3C3C3C;
                background-color: transparent;
            }
            QListWidget::item:hover {
                background-color: #3C3C3C;
            }
            QListWidget::item:selected {
                background-color: #4A90E2;
                color: white;
            }
        """)
        favorites_layout.addWidget(favorites_list)
        
        # 右下：正在播放列表和选择按钮
        playlist_widget = QWidget()
        playlist_widget.setStyleSheet("""
            QWidget {
                background-color: #2B2B2B;
                border: 1px solid #3C3C3C;
                border-radius: 5px;
            }
        """)
        playlist_layout = QVBoxLayout()
        playlist_layout.setContentsMargins(10, 10, 10, 10)
        playlist_widget.setLayout(playlist_layout)
        
        playlist_title = QLabel("正在播放列表")
        playlist_title.setStyleSheet("""
            QLabel {
                color: #A9B7C6;
                font-size: 14px;
                font-weight: bold;
                background-color: transparent;
                border: none;
                padding: 5px;
            }
        """)
        playlist_layout.addWidget(playlist_title)
        
        playlist_list = QListWidget()
        playlist_list.setStyleSheet("""
            QListWidget {
                background-color: #1E1E1E;
                color: #A9B7C6;
                border: 1px solid #3C3C3C;
                border-radius: 3px;
                padding: 5px;
                font-size: 12px;
                outline: none;
            }
            QListWidget::item {
                padding: 8px;
                border-bottom: 1px solid #3C3C3C;
                background-color: transparent;
            }
            QListWidget::item:hover {
                background-color: #3C3C3C;
            }
            QListWidget::item:selected {
                background-color: #4A90E2;
                color: white;
            }
            QListWidget::item:selected:focus {
                background-color: #5BA0F2;
            }
        """)
        playlist_layout.addWidget(playlist_list)
        
        # 选择按钮区域
        button_widget = QWidget()
        button_layout = QHBoxLayout()
        button_layout.setContentsMargins(0, 10, 0, 0)
        button_widget.setLayout(button_layout)
        
        select_file_button = QPushButton("选择文件")
        add_to_favorites_button = QPushButton("添加收藏")
        clear_playlist_button = QPushButton("清空列表")
        
        select_file_button.setStyleSheet(button_style)
        add_to_favorites_button.setStyleSheet(button_style)
        clear_playlist_button.setStyleSheet(button_style)
        
        button_layout.addWidget(select_file_button)
        button_layout.addWidget(add_to_favorites_button)
        button_layout.addWidget(clear_playlist_button)
        
        playlist_layout.addWidget(button_widget)
        
        # 将右上和右下添加到右侧分割器
        right_splitter.addWidget(favorites_widget)
        right_splitter.addWidget(playlist_widget)
        right_splitter.setStretchFactor(0, 1)  # 收藏列表
        right_splitter.setStretchFactor(1, 1)  # 播放列表
        
        # 将左右两部分添加到主分割器
        main_splitter.addWidget(left_widget)
        main_splitter.addWidget(right_splitter)
        main_splitter.setStretchFactor(0, 2)  # 左侧播放器占2/3
        main_splitter.setStretchFactor(1, 1)  # 右侧列表占1/3
        
        # 绑定按钮事件
        select_file_button.clicked.connect(self.select_media_file)
        play_button.clicked.connect(self.play_media)
        pause_button.clicked.connect(self.pause_media)
        stop_button.clicked.connect(self.stop_media)
        add_to_favorites_button.clicked.connect(self.add_to_favorites)
        clear_playlist_button.clicked.connect(self.clear_playlist)
        
        # 绑定列表双击事件
        favorites_list.itemDoubleClicked.connect(self.on_favorites_double_click)
        playlist_list.itemDoubleClicked.connect(self.on_playlist_double_click)
        
        # 存储播放器相关的UI组件引用
        self.player_display = player_display
        self.playlist_list = playlist_list
        self.favorites_list = favorites_list
        self.play_button = play_button
        self.pause_button = pause_button
        self.stop_button = stop_button
        
        # 播放器状态
        self.current_media_file = None
        self.is_playing = False
        self.is_paused = False
        self.ffplay_process = None  # ffplay进程
        self.monitor_thread = None  # 播放监控线程
        
        # 当前播放项跟踪
        self.current_playing_item = None  # 当前播放的列表项
        self.current_playing_list = None  # 当前播放项所在的列表('favorites' 或 'playlist')
        
        # 设置主布局
        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(10, 10, 10, 10)
        main_layout.addWidget(main_splitter)
        
        self.central_widget.setLayout(main_layout)

    def switch_ui(self, ui_type):
        """统一的界面切换方法"""
        # 先清空当前界面
        self.clear_central_widget_layout()
        
        # 使用短暂延迟确保界面切换流畅
        QTimer.singleShot(10, lambda: self._show_ui_delayed(ui_type))
    
    def _show_ui_delayed(self, ui_type):
        """延迟显示界面内容"""
        if ui_type == 'video':
            self.show_video_ui()
        elif ui_type == 'audio':
            self.show_audio_ui()
        elif ui_type == 'image':
            self.show_image_ui()
        elif ui_type == 'all':
            self.show_all_ui()
        elif ui_type == 'player':
            self.show_player_ui()
        elif ui_type == 'about':
            self.show_about_info()
    
    def select_media_file(self):
        """选择媒体文件"""
        try:
            file_dialog = QFileDialog()
            file_dialog.setFileMode(QFileDialog.ExistingFile)
            file_dialog.setNameFilter(
                "媒体文件 (*.mp4 *.avi *.mov *.mkv *.flv *.wmv *.mp3 *.wav *.aac *.flac *.ogg *.m4a);;"
                "视频文件 (*.mp4 *.avi *.mov *.mkv *.flv *.wmv);;"
                "音频文件 (*.mp3 *.wav *.aac *.flac *.ogg *.m4a);;"
                "所有文件 (*)"
            )
            
            if file_dialog.exec_() == QFileDialog.Accepted:
                selected_files = file_dialog.selectedFiles()
                if selected_files:
                    file_path = selected_files[0]
                    self.load_media_file(file_path)
        except Exception as e:
            QMessageBox.warning(self, "错误", f"选择文件时出错: {str(e)}")
    
    def load_media_file(self, file_path):
        """加载媒体文件"""
        try:
            # 显示加载状态
            self.player_display.setText("正在加载媒体文件...")
            QApplication.processEvents()  # 强制更新UI
            
            if not os.path.exists(file_path):
                QMessageBox.warning(self, "错误", "文件不存在")
                return
            
            self.current_media_file = file_path
            file_name = os.path.basename(file_path)
            
            # 更新播放器显示区域
            file_info = f"已加载: {file_name}\n\n文件路径: {file_path}\n\n正在自动播放..."
            self.player_display.setText(file_info)
            
            # 更新播放列表
            # 检查是否已在播放列表中
            file_exists = False
            for i in range(self.playlist_list.count()):
                item = self.playlist_list.item(i)
                if item.data(Qt.UserRole) == file_path:
                    file_exists = True
                    break
            
            # 如果不存在则添加到播放列表
            if not file_exists:
                list_item = QListWidgetItem(file_name)
                list_item.setData(Qt.UserRole, file_path)  # 存储完整文件路径
                list_item.setToolTip(file_path)  # 设置工具提示显示完整路径
                self.playlist_list.addItem(list_item)
            
            # 重置播放状态
            self.is_playing = False
            self.is_paused = False
            self.update_button_states()
            
            # 自动开始播放
            QTimer.singleShot(500, self.play_media)  # 延迟500ms后自动播放
            
        except Exception as e:
            QMessageBox.warning(self, "错误", f"加载文件时出错: {str(e)}")
    
    def play_media(self):
        """播放媒体"""
        try:
            if not self.current_media_file:
                QMessageBox.information(self, "提示", "请先选择要播放的媒体文件")
                return
            
            if not os.path.exists(self.current_media_file):
                QMessageBox.warning(self, "错误", "媒体文件不存在")
                return
            
            # 如果已经在播放，先停止
            if self.ffplay_process and self.ffplay_process.poll() is None:
                self.stop_media()
            
            self._play_media_internal()
            
        except Exception as e:
            QMessageBox.warning(self, "错误", f"播放媒体时出错: {str(e)}")
    
    def _play_media_internal(self):
        """播放媒体的内部实现"""
        try:
            
            # 确定ffplay可执行文件路径
            ffplay_path = ffplay_executable_cmd
            if not ffplay_path:
                QMessageBox.warning(self, "错误", "找不到ffplay可执行文件")
                return
            
            # 检查ffplay文件是否存在
            if not os.path.exists(ffplay_path):
                QMessageBox.warning(self, "错误", f"ffplay文件不存在: {ffplay_path}")
                return
            
            print(f"使用ffplay路径: {ffplay_path}")
            
            # 移除同步的ffplay版本检查以避免UI阻塞
            # 直接尝试启动ffplay，如果失败会在后续处理
            print(f"准备启动ffplay: {ffplay_path}")
            
            # 开始新的播放
            self.is_playing = True
            self.is_paused = False
            
            # 在macOS上，ffplay的-wid参数可能不工作，使用独立窗口模式
            # 但尝试将窗口定位到播放器区域附近
            try:
                # 获取播放器显示区域的位置和大小
                player_rect = self.player_display.geometry()
                global_pos = self.player_display.mapToGlobal(player_rect.topLeft())
                
                # 构建ffplay命令，定位到播放器区域
                cmd = [
                    ffplay_path,
                    '-x', str(player_rect.width()),  # 使用播放器区域的宽度
                    '-y', str(player_rect.height()),  # 使用播放器区域的高度
                    '-left', str(global_pos.x()),  # 窗口左边距
                    '-top', str(global_pos.y()),  # 窗口上边距
                    '-noborder',  # 无边框
                    '-alwaysontop',  # 始终保持在最上层
                    '-autoexit',  # 播放完成后自动退出
                    self.current_media_file
                ]
                print(f"播放器区域: {player_rect.width()}x{player_rect.height()} at ({global_pos.x()}, {global_pos.y()})")
            except Exception as e:
                # 如果获取位置失败，使用默认设置
                print(f"获取播放器位置失败，使用默认设置: {e}")
                cmd = [
                    ffplay_path,
                    '-x', '600',  # 窗口宽度
                    '-y', '400',  # 窗口高度
                    '-left', '50',  # 窗口左边距
                    '-top', '100',  # 窗口上边距
                    '-noborder',  # 无边框
                    '-autoexit',  # 播放完成后自动退出
                    self.current_media_file
                ]
            
            # 启动ffplay进程
            print(f"启动ffplay命令: {' '.join(cmd)}")
            try:
                self.ffplay_process = subprocess.Popen(
                    cmd,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    creationflags=subprocess.CREATE_NO_WINDOW if os.name == 'nt' else 0
                )
                print(f"ffplay进程已启动，PID: {self.ffplay_process.pid}")
            except Exception as e:
                print(f"启动ffplay进程失败: {e}")
                QMessageBox.warning(self, "错误", f"启动播放器失败: {str(e)}")
                return
            
            self.player_display.setText(
                f"正在播放: {os.path.basename(self.current_media_file)}\n\n"
                f"状态: 播放中\n\n"
                f"使用ffplay播放器"
            )
            
            # 启动监控线程检查播放状态
            self._start_playback_monitor()
            
            self.update_button_states()
            
        except Exception as e:
            print(f"_play_media_internal出错: {e}")
            # 内部方法不显示消息框，由调用者处理
    
    def pause_media(self):
        """暂停播放"""
        try:
            if not self.is_playing or not self.ffplay_process:
                QMessageBox.information(self, "提示", "当前没有正在播放的媒体")
                return
            
            # 非阻塞方式停止监控线程
            if hasattr(self, 'monitor_thread') and self.monitor_thread and self.monitor_thread.isRunning():
                self.monitor_thread.stop()
                # 移除wait()调用以避免UI阻塞
            
            # ffplay不支持暂停，只能停止播放
            # 这里我们停止当前播放，用户可以重新点击播放按钮
            if self.ffplay_process and self.ffplay_process.poll() is None:
                self.ffplay_process.terminate()
                try:
                    self.ffplay_process.wait(timeout=3)
                except subprocess.TimeoutExpired:
                    self.ffplay_process.kill()
            
            self.is_playing = False
            self.is_paused = True
            self.ffplay_process = None
            
            if self.current_media_file:
                self.player_display.setText(
                    f"已暂停: {os.path.basename(self.current_media_file)}\n\n"
                    f"状态: 暂停中\n\n"
                    f"点击播放按钮重新开始播放\n\n"
                    f"注意: ffplay不支持暂停，将从头开始播放"
                )
            
            self.update_button_states()
            
        except Exception as e:
            QMessageBox.warning(self, "错误", f"暂停时出错: {str(e)}")
    
    def stop_media(self):
        """停止播放"""
        try:
            # 停止监控线程
            if hasattr(self, 'monitor_thread') and self.monitor_thread and self.monitor_thread.isRunning():
                self.monitor_thread.stop()
                self.monitor_thread.wait()
            
            # 停止ffplay进程
            if self.ffplay_process and self.ffplay_process.poll() is None:
                self.ffplay_process.terminate()
                try:
                    self.ffplay_process.wait(timeout=3)
                except subprocess.TimeoutExpired:
                    self.ffplay_process.kill()
            
            self.is_playing = False
            self.is_paused = False
            self.ffplay_process = None
            
            # 清除播放项高亮
            if self.current_playing_item and self.current_playing_list:
                self.current_playing_item.setBackground(QColor(30, 30, 30, 0))  # 透明背景
                self.current_playing_item = None
                self.current_playing_list = None
            
            if self.current_media_file:
                self.player_display.setText(
                    f"已停止: {os.path.basename(self.current_media_file)}\n\n"
                    f"状态: 停止\n\n"
                    f"点击播放按钮重新开始播放"
                )
            
            self.update_button_states()
            
        except Exception as e:
            QMessageBox.warning(self, "错误", f"停止时出错: {str(e)}")
    
    def add_to_favorites(self):
        """添加到收藏"""
        try:
            if not self.current_media_file:
                QMessageBox.information(self, "提示", "请先选择要收藏的媒体文件")
                return
            
            file_name = os.path.basename(self.current_media_file)
            
            # 检查是否已经收藏
            for i in range(self.favorites_list.count()):
                item = self.favorites_list.item(i)
                if item.data(Qt.UserRole) == self.current_media_file:
                    QMessageBox.information(self, "提示", "该文件已在收藏列表中")
                    return
            
            # 添加到收藏列表
            list_item = QListWidgetItem(file_name)
            list_item.setData(Qt.UserRole, self.current_media_file)  # 存储完整文件路径
            list_item.setToolTip(self.current_media_file)  # 设置工具提示显示完整路径
            self.favorites_list.addItem(list_item)
            
            QMessageBox.information(self, "成功", f"已将 '{file_name}' 添加到收藏")
            
        except Exception as e:
            QMessageBox.warning(self, "错误", f"添加收藏时出错: {str(e)}")
    
    def clear_playlist(self):
        """清空播放列表"""
        try:
            reply = QMessageBox.question(
                self, "确认", "确定要清空播放列表吗？",
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.No
            )
            
            if reply == QMessageBox.Yes:
                self.playlist_list.clear()
                QMessageBox.information(self, "成功", "播放列表已清空")
                
        except Exception as e:
            QMessageBox.warning(self, "错误", f"清空列表时出错: {str(e)}")
    
    def on_favorites_double_click(self, item):
        """收藏列表双击事件处理"""
        try:
            if item and item.data(Qt.UserRole):
                file_path = item.data(Qt.UserRole)
                self._play_from_list(file_path, item, 'favorites')
        except Exception as e:
            print(f"收藏列表双击处理出错: {e}")
    
    def on_playlist_double_click(self, item):
        """播放列表双击事件处理"""
        try:
            if item and item.data(Qt.UserRole):
                file_path = item.data(Qt.UserRole)
                self._play_from_list(file_path, item, 'playlist')
        except Exception as e:
            print(f"播放列表双击处理出错: {e}")
    
    def _play_from_list(self, file_path, item, list_type):
        """从列表播放媒体文件"""
        try:
            # 停止当前播放
            if self.is_playing:
                self.stop_media()
            
            # 更新当前播放项
            self._update_playing_item_highlight(item, list_type)
            
            # 设置当前文件并播放
            self.current_media_file = file_path
            self.play_media()
            
        except Exception as e:
            QMessageBox.warning(self, "错误", f"播放文件时出错: {str(e)}")
    
    def _update_playing_item_highlight(self, new_item, list_type):
        """更新播放项高亮显示"""
        try:
            # 清除之前的高亮
            if self.current_playing_item and self.current_playing_list:
                old_list = self.favorites_list if self.current_playing_list == 'favorites' else self.playlist_list
                for i in range(old_list.count()):
                    item = old_list.item(i)
                    if item == self.current_playing_item:
                        # 恢复正常样式
                        item.setBackground(QColor(30, 30, 30, 0))  # 透明背景
                        break
            
            # 设置新的高亮
            if new_item:
                new_item.setBackground(QColor(74, 144, 226))  # 蓝色高亮
                self.current_playing_item = new_item
                self.current_playing_list = list_type
            
        except Exception as e:
            print(f"更新高亮显示出错: {e}")
    
    def update_button_states(self):
        """更新按钮状态"""
        try:
            # 根据播放状态更新按钮的可用性
            if self.current_media_file:
                self.play_button.setEnabled(not self.is_playing)
                self.pause_button.setEnabled(self.is_playing)
                self.stop_button.setEnabled(self.is_playing or self.is_paused)
            else:
                self.play_button.setEnabled(False)
                self.pause_button.setEnabled(False)
                self.stop_button.setEnabled(False)
                
        except Exception as e:
            print(f"更新按钮状态时出错: {str(e)}")
    
    def _start_playback_monitor(self):
        """启动播放监控线程"""
        try:
            # 非阻塞方式停止之前的监控线程
            if hasattr(self, 'monitor_thread') and self.monitor_thread and self.monitor_thread.isRunning():
                self.monitor_thread.quit()
                # 移除wait()调用以避免UI阻塞，让线程自然结束
            
            # 创建新的监控线程
            self.monitor_thread = PlaybackMonitorThread(self.ffplay_process, self)
            self.monitor_thread.playback_finished.connect(self._on_playback_finished)
            self.monitor_thread.start()
        except Exception as e:
            print(f"启动播放监控时出错: {str(e)}")
    
    def _on_playback_finished(self):
        """播放完成时的回调"""
        try:
            if self.current_media_file:
                self.player_display.setText(
                    f"播放完成: {os.path.basename(self.current_media_file)}\n\n"
                    f"状态: 已完成\n\n"
                    f"点击播放按钮重新播放"
                )
            self.update_button_states()
        except Exception as e:
            print(f"播放完成回调时出错: {str(e)}")
    
    def clear_central_widget_layout(self):
        """清空中央widget布局"""
        try:
            if self.central_widget and self.central_widget.layout() is not None:
                layout = self.central_widget.layout()
                while layout.count():
                    item = layout.takeAt(0)
                    if item:
                        widget = item.widget()
                        if widget is not None:
                            widget.setParent(None)
                            widget.deleteLater()
                # 删除布局并创建新的central_widget
                layout.deleteLater()
                # 创建新的central_widget替换旧的
                old_widget = self.central_widget
                self.central_widget = QWidget()
                self.setCentralWidget(self.central_widget)
                old_widget.deleteLater()
        except Exception as e:
            print(f"清空布局时出错: {e}")

    def resizeEvent(self, event):
        """窗口大小改变事件处理"""
        super().resizeEvent(event)
        
        # 如果正在播放，使用防抖定时器调整ffplay窗口大小和位置
        if hasattr(self, 'is_playing') and self.is_playing and hasattr(self, 'ffplay_process') and self.ffplay_process:
            if self.ffplay_process.poll() is None:  # 进程仍在运行
                try:
                    # 停止之前的定时器
                    self.player_position_timer.stop()
                    # 启动防抖定时器，300ms后重新启动播放器
                    self.player_position_timer.start(300)
                    
                except Exception as e:
                    print(f"调整播放器大小时出错: {e}")
    
    def moveEvent(self, event):
        """窗口位置改变事件处理"""
        super().moveEvent(event)
        
        # 如果正在播放，使用防抖定时器调整ffplay窗口位置
        if hasattr(self, 'is_playing') and self.is_playing and hasattr(self, 'ffplay_process') and self.ffplay_process:
            if self.ffplay_process.poll() is None:  # 进程仍在运行
                try:
                    # 停止之前的定时器
                    self.player_position_timer.stop()
                    # 启动防抖定时器，300ms后重新启动播放器
                    self.player_position_timer.start(300)
                    
                except Exception as e:
                    print(f"调整播放器位置时出错: {e}")
    
    def _restart_ffplay_with_new_size(self):
        """重新启动ffplay以适应新的窗口大小"""
        if not hasattr(self, 'current_media_file') or not self.current_media_file:
            return
            
        try:
            # 停止当前播放
            if self.ffplay_process and self.ffplay_process.poll() is None:
                self.ffplay_process.terminate()
                try:
                    self.ffplay_process.wait(timeout=1)
                except subprocess.TimeoutExpired:
                    self.ffplay_process.kill()
            
            # 重新开始播放（会自动使用新的窗口大小）
            QTimer.singleShot(100, self._restart_playback)
            
        except Exception as e:
            print(f"重新启动播放器时出错: {e}")
    
    def _restart_playback(self):
        """重新开始播放"""
        try:
            # 重新调用play_media，但跳过状态检查
            self._play_media_internal()
        except Exception as e:
            print(f"重新播放时出错: {e}")
    
    def closeEvent(self, event):
        """关闭事件处理"""
        try:
            if self.conversion_thread and self.conversion_thread.isRunning():
                reply = QMessageBox.question(
                    self, '确认退出', 
                    '转换正在进行中，确定要退出吗？',
                    QMessageBox.Yes | QMessageBox.No,
                    QMessageBox.No
                )
                if reply == QMessageBox.Yes:
                    # 优雅地停止线程
                    self.conversion_thread.terminate()
                    # 等待线程结束，最多等待3秒
                    if not self.conversion_thread.wait(3000):
                        print("警告：线程未能在3秒内正常结束")
                    self.conversion_thread.deleteLater()
                    self.conversion_thread = None
                    event.accept()
                else:
                    event.ignore()
            else:
                # 清理资源
                if self.conversion_thread:
                    self.conversion_thread.deleteLater()
                    self.conversion_thread = None
                event.accept()
        except Exception as e:
            print(f"关闭窗口时出错: {e}")
            event.accept()  # 即使出错也要关闭窗口
    
    def _restore_image_folder_state(self):
        """恢复图片文件夹选择状态"""
        try:
            if self.current_image_folder and os.path.exists(self.current_image_folder):
                self.image_folder_path_label.setText(os.path.basename(self.current_image_folder))
                # 扫描文件夹中的图片文件
                image_files = []
                for ext in ['*.jpg', '*.jpeg', '*.png', '*.bmp', '*.gif', '*.tiff']:
                    image_files.extend(glob.glob(os.path.join(self.current_image_folder, ext)))
                    image_files.extend(glob.glob(os.path.join(self.current_image_folder, ext.upper())))
                
                if image_files:
                    self.image_batch_convert_button.setEnabled(True)
                    # 更新文件列表显示
                    file_list_text = f"批量文件夹: {os.path.basename(self.current_image_folder)}\n"
                    file_list_text += f"包含 {len(image_files)} 个图片文件"
                    self.image_file_list.setText(file_list_text)
                else:
                    self.image_batch_convert_button.setEnabled(False)
                    self.image_file_list.setText("选择的文件夹中没有图片文件")
            else:
                self.image_folder_path_label.setText("未选择文件夹")
                self.image_batch_convert_button.setEnabled(False)
        except Exception as e:
            print(f"恢复图片文件夹状态时出错: {e}")
    
    def _select_image_folder(self):
        """选择图片文件夹"""
        try:
            folder_path = QFileDialog.getExistingDirectory(
                self, "选择图片文件夹", 
                self.current_image_folder or os.path.expanduser("~"),
                QFileDialog.DontUseNativeDialog
            )
            
            if folder_path:
                self.current_image_folder = folder_path
                self.image_folder_path_label.setText(os.path.basename(folder_path))
                
                # 扫描文件夹中的图片文件
                image_files = []
                for ext in ['*.jpg', '*.jpeg', '*.png', '*.bmp', '*.gif', '*.tiff']:
                    image_files.extend(glob.glob(os.path.join(folder_path, ext)))
                    image_files.extend(glob.glob(os.path.join(folder_path, ext.upper())))
                
                if image_files:
                    self.image_batch_convert_button.setEnabled(True)
                    # 更新文件列表显示
                    file_list_text = f"批量文件夹: {os.path.basename(folder_path)}\n"
                    file_list_text += f"包含 {len(image_files)} 个图片文件"
                    self.image_file_list.setText(file_list_text)
                    QMessageBox.information(self, "成功", f"已选择文件夹，找到 {len(image_files)} 个图片文件")
                else:
                    self.image_batch_convert_button.setEnabled(False)
                    self.image_file_list.setText("选择的文件夹中没有图片文件")
                    QMessageBox.warning(self, "警告", "选择的文件夹中没有找到图片文件")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"选择文件夹时出错: {str(e)}")
    
    def _start_image_batch_conversion(self):
        """开始图片批量转换"""
        try:
            if not self.current_image_folder or not os.path.exists(self.current_image_folder):
                QMessageBox.warning(self, "警告", "请先选择有效的图片文件夹")
                return
            
            # 扫描文件夹中的图片文件
            image_files = []
            for ext in ['*.jpg', '*.jpeg', '*.png', '*.bmp', '*.gif', '*.tiff']:
                image_files.extend(glob.glob(os.path.join(self.current_image_folder, ext)))
                image_files.extend(glob.glob(os.path.join(self.current_image_folder, ext.upper())))
            
            if not image_files:
                QMessageBox.warning(self, "警告", "选择的文件夹中没有找到图片文件")
                return
            
            # 获取输出格式
            output_format = self.image_format_combo.currentText().lower()
            
            # 创建批量转换线程
            self.batch_conversion_thread = BatchConversionThread(
                image_files, self.converter, 'image', output_format
            )
            
            # 连接信号
            self.batch_conversion_thread.progress_updated.connect(self._on_image_batch_progress)
            self.batch_conversion_thread.file_converted.connect(self._on_image_batch_file_converted)
            self.batch_conversion_thread.finished.connect(self._on_image_batch_finished)
            self.batch_conversion_thread.error.connect(self._on_image_batch_error)
            
            # 更新UI状态
            self.image_batch_convert_button.setEnabled(False)
            self.image_batch_convert_button.setText("转换中...")
            self.image_progress_bar.setVisible(True)
            self.image_progress_bar.setMaximum(len(image_files))
            self.image_progress_bar.setValue(0)
            self.image_result_text.clear()
            self.image_result_text.append(f"开始批量转换 {len(image_files)} 个图片文件...")
            
            # 启动转换线程
            self.batch_conversion_thread.start()
            
        except Exception as e:
            QMessageBox.critical(self, "错误", f"启动批量转换时出错: {str(e)}")
            self._reset_image_batch_ui()
    
    def _on_image_batch_progress(self, current, total):
        """更新图片批量转换进度"""
        try:
            # 确保在主线程中执行UI更新
            if not self.thread() == QApplication.instance().thread():
                QTimer.singleShot(0, lambda: self._update_image_batch_progress_ui(current, total))
                return
            
            self._update_image_batch_progress_ui(current, total)
        except Exception as e:
            print(f"更新图片批量转换进度时出错: {e}")
    
    def _update_image_batch_progress_ui(self, current, total):
        """在主线程中更新图片批量转换进度UI"""
        try:
            if hasattr(self, 'image_progress_bar') and self.image_progress_bar:
                # 确保进度条有效且可见
                if not self.image_progress_bar.isVisible():
                    self.image_progress_bar.setVisible(True)
                
                # 安全地设置最大值和当前值
                if self.image_progress_bar.maximum() != total:
                    self.image_progress_bar.setMaximum(total)
                
                self.image_progress_bar.setValue(current)
                
                # 强制刷新UI
                self.image_progress_bar.repaint()
                QApplication.processEvents()
            
            if hasattr(self, 'image_result_text') and self.image_result_text:
                progress_text = f"正在转换第 {current}/{total} 个文件..."
                self.image_result_text.append(progress_text)
        except Exception as e:
            print(f"更新图片批量转换进度UI时出错: {e}")
    
    def _on_image_batch_file_converted(self, file_path, success, message):
        """处理图片批量转换单个文件结果"""
        try:
            file_name = os.path.basename(file_path)
            if success:
                self.image_result_text.append(f"✓ {file_name} - 转换成功")
            else:
                self.image_result_text.append(f"✗ {file_name} - 转换失败: {message}")
        except Exception as e:
            print(f"处理图片批量转换文件结果时出错: {e}")
    
    def _on_image_batch_finished(self, total_files, successful_files):
        """图片批量转换完成"""
        try:
            failed_files = total_files - successful_files
            self.image_result_text.append(f"\n批量转换完成!")
            self.image_result_text.append(f"总文件数: {total_files}")
            self.image_result_text.append(f"成功: {successful_files}")
            self.image_result_text.append(f"失败: {failed_files}")
            
            self._reset_image_batch_ui()
            
            if failed_files == 0:
                QMessageBox.information(self, "完成", f"批量转换完成！\n成功转换 {successful_files} 个文件")
            else:
                QMessageBox.warning(self, "完成", f"批量转换完成！\n成功: {successful_files}\n失败: {failed_files}")
        except Exception as e:
            print(f"处理图片批量转换完成时出错: {e}")
            self._reset_image_batch_ui()
    
    def _on_image_batch_error(self, error_message):
        """处理图片批量转换错误"""
        try:
            self.image_result_text.append(f"\n批量转换出错: {error_message}")
            self._reset_image_batch_ui()
            QMessageBox.critical(self, "错误", f"批量转换出错: {error_message}")
        except Exception as e:
            print(f"处理图片批量转换错误时出错: {e}")
    
    def _reset_image_batch_ui(self):
        """重置图片批量转换UI状态"""
        try:
            self.image_batch_convert_button.setEnabled(True)
            self.image_batch_convert_button.setText("开始批量转换")
            self.image_progress_bar.setVisible(False)
        except Exception as e:
            print(f"重置图片批量转换UI状态时出错: {e}")

    def show_all_ui(self):
        """显示全部转换界面"""
        main_layout = QVBoxLayout()
        main_layout.setSpacing(0)
        main_layout.setContentsMargins(15, 15, 15, 15)

        # 顶部标题区域
        title_widget = QWidget()
        title_widget.setFixedHeight(60)
        title_layout = QVBoxLayout()
        title_layout.setContentsMargins(0, 0, 0, 0)
        title_widget.setLayout(title_layout)
        
        title = QLabel("全部转换")
        title.setStyleSheet(style_manager.get_interface_title_style())
        title.setAlignment(Qt.AlignCenter)
        title_layout.addWidget(title)
        main_layout.addWidget(title_widget)

        # 中间内容区域
        middle_widget = QWidget()
        middle_layout = QHBoxLayout()
        middle_layout.setSpacing(20)
        middle_layout.setContentsMargins(0, 20, 0, 20)
        middle_widget.setLayout(middle_layout)
        
        # 左侧文件夹选择区域 - 占一半
        left_widget = QWidget()
        left_widget.setStyleSheet(style_manager.get_left_widget_style())
        left_layout = QVBoxLayout()
        left_layout.setContentsMargins(20, 20, 20, 20)
        left_layout.setSpacing(30)
        left_widget.setLayout(left_layout)
        
        # 原文件夹选择器
        source_folder_widget = QWidget()
        source_folder_layout = QVBoxLayout()
        source_folder_layout.setSpacing(10)
        source_folder_widget.setLayout(source_folder_layout)
        
        source_folder_title = QLabel("原文件夹")
        source_folder_title.setStyleSheet(style_manager.get_file_list_title_style())
        source_folder_layout.addWidget(source_folder_title)
        
        source_folder_select_widget = QWidget()
        source_folder_select_layout = QHBoxLayout()
        source_folder_select_widget.setLayout(source_folder_select_layout)
        
        self.all_source_folder_button = QPushButton("选择原文件夹")
        self.all_source_folder_button.setStyleSheet(style_manager.get_folder_button_style())
        
        self.all_source_folder_label = QLabel("未选择文件夹")
        self.all_source_folder_label.setStyleSheet(style_manager.get_path_label_style())
        
        source_folder_select_layout.addWidget(self.all_source_folder_button)
        source_folder_select_layout.addWidget(self.all_source_folder_label, 1)
        source_folder_layout.addWidget(source_folder_select_widget)
        
        # 目标文件夹选择器
        target_folder_widget = QWidget()
        target_folder_layout = QVBoxLayout()
        target_folder_layout.setSpacing(10)
        target_folder_widget.setLayout(target_folder_layout)
        
        target_folder_title = QLabel("目标文件夹")
        target_folder_title.setStyleSheet(style_manager.get_file_list_title_style())
        target_folder_layout.addWidget(target_folder_title)
        
        target_folder_select_widget = QWidget()
        target_folder_select_layout = QHBoxLayout()
        target_folder_select_widget.setLayout(target_folder_select_layout)
        
        self.all_target_folder_button = QPushButton("选择目标文件夹")
        self.all_target_folder_button.setStyleSheet(style_manager.get_folder_button_style())
        
        self.all_target_folder_label = QLabel("未选择文件夹")
        self.all_target_folder_label.setStyleSheet(style_manager.get_path_label_style())
        
        target_folder_select_layout.addWidget(self.all_target_folder_button)
        target_folder_select_layout.addWidget(self.all_target_folder_label, 1)
        target_folder_layout.addWidget(target_folder_select_widget)
        
        left_layout.addWidget(source_folder_widget)
        left_layout.addWidget(target_folder_widget)
        left_layout.addStretch()
        
        # 右侧转换按钮区域 - 占一半
        right_widget = QWidget()
        right_layout = QVBoxLayout()
        right_layout.setContentsMargins(20, 20, 20, 20)
        right_widget.setLayout(right_layout)
        
        # 转换全部按钮
        self.all_convert_button = QPushButton("转换全部")
        self.all_convert_button.setStyleSheet(style_manager.get_batch_convert_button_style())
        self.all_convert_button.setEnabled(False)
        self.all_convert_button.setMinimumHeight(80)
        
        right_layout.addStretch()
        right_layout.addWidget(self.all_convert_button)
        right_layout.addStretch()
        
        # 设置左右比例 1:1
        middle_layout.addWidget(left_widget, 1)
        middle_layout.addWidget(right_widget, 1)
        main_layout.addWidget(middle_widget, 7)

        # 底部信息提示区域
        bottom_widget = QWidget()
        bottom_widget.setFixedHeight(120)
        bottom_layout = QVBoxLayout()
        bottom_layout.setContentsMargins(0, 10, 0, 0)
        bottom_widget.setLayout(bottom_layout)
        
        # 进度条
        self.all_progress_bar = QProgressBar()
        self.all_progress_bar.setVisible(False)
        self.all_progress_bar.setMinimum(0)
        self.all_progress_bar.setMaximum(100)
        self.all_progress_bar.setValue(0)
        self.all_progress_bar.setTextVisible(True)
        bottom_layout.addWidget(self.all_progress_bar)
        
        # 信息显示区域
        self.all_result_text = QTextEdit()
        self.all_result_text.setReadOnly(True)
        self.all_result_text.setStyleSheet(style_manager.get_result_text_style())
        self.all_result_text.setPlaceholderText("支持批量转换文件夹中的所有视频、音频和图片文件")
        self.all_result_text.setMinimumHeight(100)
        self.all_result_text.setMaximumHeight(300)
        bottom_layout.addWidget(self.all_result_text)
        main_layout.addWidget(bottom_widget, 2)

        self.central_widget.setLayout(main_layout)
        
        # 绑定事件
        self.all_source_folder_button.clicked.connect(self._select_all_source_folder)
        self.all_target_folder_button.clicked.connect(self._select_all_target_folder)
        self.all_convert_button.clicked.connect(self._start_all_conversion)
        
        # 恢复之前的文件夹选择状态
        self._restore_all_folder_state()

    def _select_all_source_folder(self):
        """选择原文件夹"""
        try:
            folder_path = QFileDialog.getExistingDirectory(
                self, 
                "选择原文件夹", 
                "",
                options=QFileDialog.DontUseNativeDialog
            )
            if folder_path:
                self.all_source_folder = folder_path
                self.all_source_folder_label.setText(os.path.basename(folder_path))
                self._check_all_folders_selected()
                if hasattr(self, 'all_result_text') and self.all_result_text:
                    self.all_result_text.clear()
        except Exception as e:
            QMessageBox.critical(self, "错误", f"选择原文件夹时出错: {str(e)}")

    def _select_all_target_folder(self):
        """选择目标文件夹"""
        try:
            folder_path = QFileDialog.getExistingDirectory(
                self, 
                "选择目标文件夹", 
                "",
                options=QFileDialog.DontUseNativeDialog
            )
            if folder_path:
                self.all_target_folder = folder_path
                self.all_target_folder_label.setText(os.path.basename(folder_path))
                self._check_all_folders_selected()
                if hasattr(self, 'all_result_text') and self.all_result_text:
                    self.all_result_text.clear()
        except Exception as e:
            QMessageBox.critical(self, "错误", f"选择目标文件夹时出错: {str(e)}")

    def _check_all_folders_selected(self):
        """检查是否已选择所有必要的文件夹"""
        try:
            if (hasattr(self, 'all_convert_button') and 
                self.all_source_folder and 
                self.all_target_folder and 
                os.path.exists(self.all_source_folder) and 
                os.path.exists(self.all_target_folder)):
                self.all_convert_button.setEnabled(True)
            elif hasattr(self, 'all_convert_button'):
                self.all_convert_button.setEnabled(False)
        except Exception as e:
            print(f"检查文件夹选择状态时出错: {e}")

    def _start_all_conversion(self):
        """开始全部转换"""
        try:
            if not self.all_source_folder or not self.all_target_folder:
                QMessageBox.warning(self, "警告", "请先选择原文件夹和目标文件夹")
                return
            
            if not os.path.exists(self.all_source_folder):
                QMessageBox.warning(self, "警告", "原文件夹不存在")
                return
            
            if not os.path.exists(self.all_target_folder):
                QMessageBox.warning(self, "警告", "目标文件夹不存在")
                return
            
            # 递归扫描原文件夹中的所有媒体文件
            all_files = self._scan_media_files_recursive(self.all_source_folder)
            
            if not all_files:
                QMessageBox.information(self, "提示", "原文件夹中没有找到支持的媒体文件")
                return
            
            # 显示确认对话框
            reply = QMessageBox.question(
                self, '确认转换', 
                f'找到 {len(all_files)} 个文件，确定要开始转换吗？',
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.No
            )
            
            if reply == QMessageBox.Yes:
                self.all_result_text.clear()
                self.all_result_text.append(f"开始转换 {len(all_files)} 个文件...")
                self.all_progress_bar.setVisible(True)
                self.all_progress_bar.setValue(0)
                self.all_convert_button.setEnabled(False)
                self.all_convert_button.setText("转换中...")
                
                # 启动转换线程
                self.all_conversion_thread = AllConversionThread(
                    all_files, self.all_source_folder, self.all_target_folder
                )
                self.all_conversion_thread.progress_updated.connect(self._update_all_progress)
                self.all_conversion_thread.file_converted.connect(self._on_all_file_converted)
                self.all_conversion_thread.conversion_finished.connect(self._on_all_conversion_finished)
                self.all_conversion_thread.error_occurred.connect(self._on_all_conversion_error)
                self.all_conversion_thread.start()
                
        except Exception as e:
            QMessageBox.critical(self, "错误", f"开始转换时出错: {str(e)}")

    def _scan_media_files_recursive(self, folder_path):
        """递归扫描文件夹中的所有媒体文件"""
        all_files = []
        
        # 支持的文件扩展名
        video_exts = ['.mp4', '.avi', '.mov', '.mkv', '.flv', '.wmv']
        audio_exts = ['.mp3', '.wav', '.aac', '.flac', '.ogg', '.m4a']
        image_exts = ['.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff']
        
        supported_exts = video_exts + audio_exts + image_exts
        
        for root, dirs, files in os.walk(folder_path):
            for file in files:
                file_ext = os.path.splitext(file)[1].lower()
                if file_ext in supported_exts:
                    file_path = os.path.join(root, file)
                    all_files.append(file_path)
        
        return all_files
    
    def _update_all_progress(self, progress):
        """更新全部转换进度"""
        self.all_progress_bar.setValue(progress)
    
    def _on_all_file_converted(self, file_info):
        """单个文件转换完成"""
        self.all_result_text.append(file_info)
    
    def _on_all_conversion_finished(self, total_files, success_count, error_count):
        """全部转换完成"""
        self.all_progress_bar.setValue(100)
        self.all_result_text.append(f"\n转换完成！")
        self.all_result_text.append(f"总文件数: {total_files}")
        self.all_result_text.append(f"成功转换: {success_count}")
        self.all_result_text.append(f"转换失败: {error_count}")
        
        self.all_convert_button.setEnabled(True)
        self.all_convert_button.setText("转换全部")
        QTimer.singleShot(3000, lambda: self.all_progress_bar.setVisible(False))
    
    def _on_all_conversion_error(self, error_msg):
        """转换过程中出现错误"""
        self.all_result_text.append(f"错误: {error_msg}")
        self.all_convert_button.setEnabled(True)
        self.all_convert_button.setText("转换全部")

    def _restore_all_folder_state(self):
        """恢复全部转换的文件夹选择状态"""
        try:
            if self.all_source_folder and os.path.exists(self.all_source_folder):
                self.all_source_folder_label.setText(os.path.basename(self.all_source_folder))
            
            if self.all_target_folder and os.path.exists(self.all_target_folder):
                self.all_target_folder_label.setText(os.path.basename(self.all_target_folder))
            
            self._check_all_folders_selected()
        except Exception as e:
            print(f"恢复全部转换文件夹状态时出错: {e}")
    
    def closeEvent(self, event):
        """窗口关闭事件处理"""
        try:
            # 停止播放和清理资源
            if hasattr(self, 'ffplay_process') and self.ffplay_process:
                if self.ffplay_process.poll() is None:
                    self.ffplay_process.terminate()
                    try:
                        self.ffplay_process.wait(timeout=3)
                    except subprocess.TimeoutExpired:
                        self.ffplay_process.kill()
            
            # 停止监控线程
            if hasattr(self, 'monitor_thread') and self.monitor_thread and self.monitor_thread.isRunning():
                self.monitor_thread.stop()
                self.monitor_thread.wait()
            
            # 停止转换线程
            if hasattr(self, 'conversion_thread') and self.conversion_thread and self.conversion_thread.isRunning():
                self.conversion_thread.quit()
                self.conversion_thread.wait()
            
            event.accept()
        except Exception as e:
            print(f"关闭窗口时出错: {str(e)}")
            event.accept()


if __name__ == "__main__":
    import sys
    
    try:
        # 启用高DPI支持
        QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
        QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
        
        app = QApplication(sys.argv)
        
        # 设置应用程序属性以确保跨平台一致性
        app.setStyle('Fusion')  # 使用Fusion样式确保跨平台一致性
        
        # 设置应用程序信息
        app.setApplicationName("多媒体转换工具")
        app.setApplicationVersion("1.0")
        app.setOrganizationName("Jake")
        
        try:
            window = MainWindow()
            window.show()
        except Exception as e:
            QMessageBox.critical(None, "启动错误", f"程序启动失败: {str(e)}")
            sys.exit(1)
        
        sys.exit(app.exec_())
    except Exception as e:
        print(f"程序启动时发生严重错误: {e}")
        import traceback
        traceback.print_exc()
        sys.exit(1)
